blob: e2a87e372195399687d741d2129cdeb53cb4890c [file] [log] [blame]
Brad Bishop3d57f502016-10-19 12:18:41 -04001#pragma once
2
3#include <utility>
4#include <memory>
5#include <sdbusplus/message.hpp>
Brad Bishop65ffffa2016-11-29 12:31:31 -05006#include "utils.hpp"
Brad Bishop3d57f502016-10-19 12:18:41 -04007
8namespace phosphor
9{
10namespace inventory
11{
12namespace manager
13{
Brad Bishopc0eae112016-10-19 21:59:47 -040014
15class Manager;
Brad Bishop65ffffa2016-11-29 12:31:31 -050016namespace details
17{
18using FilterBase = holder::CallableBase<
19 bool, sdbusplus::message::message&, Manager&>;
20using FilterBasePtr = std::shared_ptr<FilterBase>;
21template <typename T>
22using Filter = holder::CallableHolder<
23 T, bool, sdbusplus::message::message&, Manager&>;
24
25/** @brief make_filter
26 *
27 * Adapt a filter function object.
28 *
29 * @param[in] filter - The filter being adapted.
30 * @returns - The adapted filter.
31 *
32 * @tparam T - The type of the filter being adapted.
33 */
34template <typename T>
35auto make_filter(T&& filter)
36{
37 return Filter<T>::template make_shared<Filter<T>>(
38 std::forward<T>(filter));
39}
40} // namespace details
41
Brad Bishop3d57f502016-10-19 12:18:41 -040042namespace filters
43{
44namespace details
45{
Brad Bishopbf5aa9c2016-10-19 21:19:04 -040046namespace property_condition
47{
48
49/** @struct PropertyCondition
50 * @brief Match filter functor that tests a property value.
51 *
52 * @tparam T - The type of the property being tested.
53 * @tparam U - The type of the condition checking functor.
54 */
55template <typename T, typename U>
56struct PropertyCondition
57{
58 PropertyCondition() = delete;
59 ~PropertyCondition() = default;
60 PropertyCondition(const PropertyCondition&) = default;
61 PropertyCondition & operator=(const PropertyCondition&) = delete;
62 PropertyCondition(PropertyCondition&&) = default;
63 PropertyCondition& operator=(PropertyCondition&&) = default;
64 PropertyCondition(const char *iface, const char *property, U &&condition) :
65 _iface(iface),
66 _property(property),
67 _condition(std::forward<U>(condition)) { }
68
69 /** @brief Test a property value.
70 *
71 * Extract the property from the PropertiesChanged
72 * message and run the condition test.
73 */
Brad Bishopc0eae112016-10-19 21:59:47 -040074 bool operator()(sdbusplus::message::message &msg, Manager &) const
Brad Bishopbf5aa9c2016-10-19 21:19:04 -040075 {
76 std::map<
77 std::string,
78 sdbusplus::message::variant<T>> properties;
79 const char *iface = nullptr;
80
81 msg.read(iface);
82 if(strcmp(iface, _iface))
83 return false;
84
85 msg.read(properties);
86 auto it = properties.find(_property);
87 if(it == properties.cend())
88 return false;
89
90 return _condition(it->second);
91 }
92
93 private:
94 const char *_iface;
95 const char *_property;
96 U _condition;
97};
98
99} // namespace property_condition
Brad Bishop3d57f502016-10-19 12:18:41 -0400100} // namespace details
101
102/** @brief The default filter. */
Brad Bishopc0eae112016-10-19 21:59:47 -0400103inline bool none(sdbusplus::message::message &, Manager &) noexcept
Brad Bishop3d57f502016-10-19 12:18:41 -0400104{
105 return true;
106}
107
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400108/** @brief Implicit type deduction for constructing PropertyCondition. */
109template <typename T>
110auto propertyChangedTo(
111 const char *iface,
112 const char *property,
113 T val)
114{
115 auto condition = [val = std::move(val)](auto arg){return arg == val;};
116 using U = decltype(condition);
117 return details::property_condition::PropertyCondition<T, U>(
118 iface, property, std::move(condition));
119}
120
Brad Bishop3d57f502016-10-19 12:18:41 -0400121} // namespace filters
122} // namespace manager
123} // namespace inventory
124} // namespace phosphor
125
126// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4