1 #include "utils/conversion_trigger.hpp"
2 
3 #include "utils/transform.hpp"
4 #include "utils/tstring.hpp"
5 
6 #include <sdbusplus/exception.hpp>
7 
8 namespace utils
9 {
10 namespace ts = utils::tstring;
11 
operator ()(const std::monostate & arg) const12 LabeledTriggerThresholdParams ToLabeledThresholdParamConversion::operator()(
13     const std::monostate& arg) const
14 {
15     throw sdbusplus::exception::SdBusError(
16         static_cast<int>(std::errc::invalid_argument),
17         "Provided threshold parameter is invalid");
18 }
19 
operator ()(const std::vector<numeric::ThresholdParam> & arg) const20 LabeledTriggerThresholdParams ToLabeledThresholdParamConversion::operator()(
21     const std::vector<numeric::ThresholdParam>& arg) const
22 {
23     return utils::transform(arg, [](const auto& thresholdParam) {
24         const auto& [type, dwellTime, direction,
25                      thresholdValue] = thresholdParam;
26         return numeric::LabeledThresholdParam(numeric::toType(type), dwellTime,
27                                               numeric::toDirection(direction),
28                                               thresholdValue);
29     });
30 }
31 
operator ()(const std::vector<discrete::ThresholdParam> & arg) const32 LabeledTriggerThresholdParams ToLabeledThresholdParamConversion::operator()(
33     const std::vector<discrete::ThresholdParam>& arg) const
34 {
35     return utils::transform(arg, [](const auto& thresholdParam) {
36         const auto& [userId, severity, dwellTime,
37                      thresholdValue] = thresholdParam;
38         return discrete::LabeledThresholdParam(
39             userId, utils::toSeverity(severity), dwellTime, thresholdValue);
40     });
41 }
42 
operator ()(const std::vector<numeric::LabeledThresholdParam> & arg) const43 TriggerThresholdParams FromLabeledThresholdParamConversion::operator()(
44     const std::vector<numeric::LabeledThresholdParam>& arg) const
45 {
46     return utils::transform(
47         arg, [](const numeric::LabeledThresholdParam& labeledThresholdParam) {
48         return numeric::ThresholdParam(
49             numeric::typeToString(labeledThresholdParam.at_label<ts::Type>()),
50             labeledThresholdParam.at_label<ts::DwellTime>(),
51             numeric::directionToString(
52                 labeledThresholdParam.at_label<ts::Direction>()),
53             labeledThresholdParam.at_label<ts::ThresholdValue>());
54     });
55 }
56 
operator ()(const std::vector<discrete::LabeledThresholdParam> & arg) const57 TriggerThresholdParams FromLabeledThresholdParamConversion::operator()(
58     const std::vector<discrete::LabeledThresholdParam>& arg) const
59 {
60     return utils::transform(
61         arg, [](const discrete::LabeledThresholdParam& labeledThresholdParam) {
62         return discrete::ThresholdParam(
63             labeledThresholdParam.at_label<ts::UserId>(),
64             utils::enumToString(labeledThresholdParam.at_label<ts::Severity>()),
65             labeledThresholdParam.at_label<ts::DwellTime>(),
66             labeledThresholdParam.at_label<ts::ThresholdValue>());
67     });
68 }
69 
fromLabeledSensorsInfo(const std::vector<LabeledSensorInfo> & infos)70 SensorsInfo fromLabeledSensorsInfo(const std::vector<LabeledSensorInfo>& infos)
71 {
72     return utils::transform(infos, [](const LabeledSensorInfo& val) {
73         return SensorsInfo::value_type(
74             sdbusplus::message::object_path(val.at_label<ts::Path>()),
75             val.at_label<ts::Metadata>());
76     });
77 }
78 
79 TriggerThresholdParams
fromLabeledThresholdParam(const std::vector<LabeledThresholdParam> & params)80     fromLabeledThresholdParam(const std::vector<LabeledThresholdParam>& params)
81 {
82     namespace ts = utils::tstring;
83     if (params.empty())
84     {
85         return std::vector<numeric::ThresholdParam>();
86     }
87 
88     if (isFirstElementOfType<std::monostate>(params))
89     {
90         return std::vector<discrete::ThresholdParam>();
91     }
92 
93     if (isFirstElementOfType<discrete::LabeledThresholdParam>(params))
94     {
95         return utils::transform(params, [](const auto& param) {
96             const discrete::LabeledThresholdParam* paramUnpacked =
97                 std::get_if<discrete::LabeledThresholdParam>(&param);
98             if (!paramUnpacked)
99             {
100                 throw std::runtime_error(
101                     "Mixing threshold types is not allowed");
102             }
103             return discrete::ThresholdParam(
104                 paramUnpacked->at_label<ts::UserId>(),
105                 utils::enumToString(paramUnpacked->at_label<ts::Severity>()),
106                 paramUnpacked->at_label<ts::DwellTime>(),
107                 paramUnpacked->at_label<ts::ThresholdValue>());
108         });
109     }
110 
111     if (isFirstElementOfType<numeric::LabeledThresholdParam>(params))
112     {
113         return utils::transform(params, [](const auto& param) {
114             const numeric::LabeledThresholdParam* paramUnpacked =
115                 std::get_if<numeric::LabeledThresholdParam>(&param);
116             if (!paramUnpacked)
117             {
118                 throw std::runtime_error(
119                     "Mixing threshold types is not allowed");
120             }
121             return numeric::ThresholdParam(
122                 numeric::typeToString(paramUnpacked->at_label<ts::Type>()),
123                 paramUnpacked->at_label<ts::DwellTime>(),
124                 numeric::directionToString(
125                     paramUnpacked->at_label<ts::Direction>()),
126                 paramUnpacked->at_label<ts::ThresholdValue>());
127         });
128     }
129 
130     throw std::runtime_error("Incorrect threshold params");
131 }
132 
labeledThresholdParamsToJson(const LabeledTriggerThresholdParams & labeledThresholdParams)133 nlohmann::json labeledThresholdParamsToJson(
134     const LabeledTriggerThresholdParams& labeledThresholdParams)
135 {
136     return std::visit([](const auto& lt) { return nlohmann::json(lt); },
137                       labeledThresholdParams);
138 }
139 
stodStrict(const std::string & str)140 double stodStrict(const std::string& str)
141 {
142     size_t pos = 0;
143     double result = std::stod(str, &pos);
144     if (pos < str.length())
145     {
146         throw std::invalid_argument(
147             "non-numeric characters at the end of string");
148     }
149     return result;
150 }
151 
152 } // namespace utils
153