| 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); |