xaizek / dit (License: GPLv3) (since 2018-12-07)
Command-line task keeper that remembers all old values and is meant to combine several orthogonal features to be rather flexible in managing items.
Commit 2c70f5c0814e91e352eb282492a619995adc63e6

Make accessor of ItemFilter return a vector
Author: xaizek
Author date (UTC): 2018-10-31 21:26
Committer name: xaizek
Committer date (UTC): 2018-10-31 21:26
Parent(s): efb8eada2ce6d9456727593c666d0bdb94573df3
Signing key: 99DC5E4DB05F6BE2
Tree: 2724bb7b5626ed5dee738a49567f26fd278074f8
File Lines added Lines deleted
src/ItemFilter.cpp 13 6
src/ItemFilter.hpp 10 3
src/cmds/AddCmd.cpp 2 1
tests/ItemFilter.cpp 3 1
File src/ItemFilter.cpp changed (mode: 100644) (index 46c3eff..56abf20)
... ... ItemFilter::~ItemFilter()
53 53 bool bool
54 54 ItemFilter::passes(Item &item) const ItemFilter::passes(Item &item) const
55 55 { {
56 return passes([&item](const std::string &f) { return item.getValue(f); });
56 return passes([&item](const std::string &f) {
57 return std::vector<std::string>{ item.getValue(f) };
58 });
57 59 } }
58 60
59 61 bool bool
60 ItemFilter::passes(std::function<std::string(const std::string &)> accessor)
61 const
62 ItemFilter::passes(std::function<accessor_f> accessor) const
62 63 { {
63 64 std::string error; std::string error;
64 65 return passes(accessor, error); return passes(accessor, error);
65 66 } }
66 67
67 68 bool bool
68 ItemFilter::passes(std::function<std::string(const std::string &)> accessor,
69 std::string &error) const
69 ItemFilter::passes(std::function<accessor_f> accessor, std::string &error) const
70 70 { {
71 71 error.clear(); error.clear();
72 72
 
... ... ItemFilter::passes(std::function<std::string(const std::string &)> accessor,
89 89 }; };
90 90
91 91 for (const Cond &cond : conds) { for (const Cond &cond : conds) {
92 if (!test(cond, accessor(cond.key))) {
92 bool matched = false;
93 for (const std::string &val : accessor(cond.key)) {
94 if (test(cond, val)) {
95 matched = true;
96 break;
97 }
98 }
99 if (!matched) {
93 100 err(cond); err(cond);
94 101 } }
95 102 } }
File src/ItemFilter.hpp changed (mode: 100644) (index d1f6836..b8c716b)
... ... class Item;
34 34 */ */
35 35 class ItemFilter class ItemFilter
36 36 { {
37 /**
38 * @brief Type of function that is used to query field value.
39 *
40 * A field can be expanded to zero, one or multiple values and each value
41 * will be matched individually.
42 */
43 using accessor_f = std::vector<std::string>(const std::string &key);
44
37 45 public: public:
38 46 /** /**
39 47 * @brief Constructs the filter out of conditions in textual form. * @brief Constructs the filter out of conditions in textual form.
 
... ... public:
72 80 * *
73 81 * @returns @c true if it passes, and @c false otherwise. * @returns @c true if it passes, and @c false otherwise.
74 82 */ */
75 bool passes(std::function<std::string(const std::string &)> accessor) const;
83 bool passes(std::function<accessor_f> accessor) const;
76 84
77 85 /** /**
78 86 * @brief Checks whether item represented by its fields passes the filter. * @brief Checks whether item represented by its fields passes the filter.
 
... ... public:
82 90 * *
83 91 * @returns @c true if it passes, and @c false otherwise. * @returns @c true if it passes, and @c false otherwise.
84 92 */ */
85 bool passes(std::function<std::string(const std::string &)> accessor,
86 std::string &error) const;
93 bool passes(std::function<accessor_f> accessor, std::string &error) const;
87 94
88 95 private: private:
89 96 /** /**
File src/cmds/AddCmd.cpp changed (mode: 100644) (index 0ee0412..ffdf63d)
... ... AddCmd::run(Project &project, const std::vector<std::string> &args)
125 125
126 126 std::string guard = cfg.get("guards.newitem", std::string()); std::string guard = cfg.get("guards.newitem", std::string());
127 127 auto accessor = [&fields](const std::string &f) { auto accessor = [&fields](const std::string &f) {
128 using return_t = std::vector<std::string>;
128 129 auto it = fields.find(f); auto it = fields.find(f);
129 return (it == fields.cend()) ? std::string() : it->second;
130 return (it == fields.cend()) ? return_t{} : return_t{ it->second };
130 131 }; };
131 132 std::string error; std::string error;
132 133 if (!ItemFilter(breakIntoArgs(guard)).passes(accessor, error)) { if (!ItemFilter(breakIntoArgs(guard)).passes(accessor, error)) {
File tests/ItemFilter.cpp changed (mode: 100644) (index a180990..1c3b2f1)
... ... TEST_CASE("Error messages add up", "[item-filter]")
40 40 ItemFilter filter({ "_id==notid", "title!=title", "_id!/ID", "title/xy" }); ItemFilter filter({ "_id==notid", "title!=title", "_id!/ID", "title/xy" });
41 41
42 42 std::string error; std::string error;
43 auto accessor = [&item](const std::string &f) { return item.getValue(f); };
43 auto accessor = [&item](const std::string &f) {
44 return std::vector<std::string>{ item.getValue(f) };
45 };
44 46 REQUIRE(!filter.passes(accessor, error)); REQUIRE(!filter.passes(accessor, error));
45 47
46 48 REQUIRE(split(error, '\n').size() == 4); REQUIRE(split(error, '\n').size() == 4);
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/dit

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/dit

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master