rsl 1.1.0
ROS Support Library
Loading...
Searching...
No Matches
parameter_validators.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <rsl/algorithm.hpp>
4#include <rsl/export.hpp>
7
8#include <rcl_interfaces/msg/set_parameters_result.hpp>
9#include <rclcpp/parameter.hpp>
10#include <tl_expected/expected.hpp>
11
12#include <fmt/ranges.h>
13
14namespace rsl {
15
21namespace detail {
22template <typename T, typename Fn>
23[[nodiscard]] auto size_compare(rclcpp::Parameter const& parameter, size_t const size,
24 std::string const& predicate_description, Fn const& predicate)
25 -> tl::expected<void, std::string> {
26 static constexpr auto format_string = "Length of parameter '{}' is '{}' but must be {} '{}'";
27 switch (parameter.get_type()) {
28 case rclcpp::ParameterType::PARAMETER_STRING:
29 if (auto value = parameter.get_value<std::string>(); !predicate(value.size(), size))
30 return tl::unexpected(fmt::format(format_string, parameter.get_name(), value.size(),
31 predicate_description, size));
32 break;
33 default:
34 if (auto value = parameter.get_value<std::vector<T>>(); !predicate(value.size(), size))
35 return tl::unexpected(fmt::format(format_string, parameter.get_name(), value.size(),
36 predicate_description, size));
37 }
38 return {};
39}
40
41template <typename T, typename Fn>
42[[nodiscard]] auto compare(rclcpp::Parameter const& parameter, T const& value,
43 std::string const& predicate_description, Fn const& predicate)
44 -> tl::expected<void, std::string> {
45 if (auto const param_value = parameter.get_value<T>(); !predicate(param_value, value))
46 return tl::unexpected(fmt::format("Parameter '{}' with the value '{}' must be {} '{}'",
47 parameter.get_name(), param_value, predicate_description,
48 value));
49 return {};
50}
51} // namespace detail
62template <typename T>
63[[nodiscard]] auto unique(rclcpp::Parameter const& parameter) -> tl::expected<void, std::string> {
64 if (is_unique(parameter.get_value<std::vector<T>>())) return {};
65 return tl::unexpected(
66 fmt::format("Parameter '{}' must only contain unique values", parameter.get_name()));
67}
68
75template <typename T>
76[[nodiscard]] auto subset_of(rclcpp::Parameter const& parameter, std::vector<T> const& valid_values)
77 -> tl::expected<void, std::string> {
78 auto const& values = parameter.get_value<std::vector<T>>();
79 for (auto const& value : values)
80 if (!contains(valid_values, value))
81 return tl::unexpected(
82 fmt::format("Entry '{}' in parameter '{}' is not in the set '{{{}}}'", value,
83 parameter.get_name(), fmt::join(valid_values, ", ")));
84 return {};
85}
86
93template <typename T>
94[[nodiscard]] auto fixed_size(rclcpp::Parameter const& parameter, size_t const size) {
95 return detail::size_compare<T>(parameter, size, "equal to", std::equal_to<>());
96}
97
104template <typename T>
105[[nodiscard]] auto size_gt(rclcpp::Parameter const& parameter, size_t const size) {
106 return detail::size_compare<T>(parameter, size, "greater than", std::greater<>());
107}
108
115template <typename T>
116[[nodiscard]] auto size_lt(rclcpp::Parameter const& parameter, size_t const size) {
117 return detail::size_compare<T>(parameter, size, "less than", std::less<>());
118}
119
127template <typename T>
128[[nodiscard]] auto not_empty(rclcpp::Parameter const& parameter)
129 -> tl::expected<void, std::string> {
130 switch (parameter.get_type()) {
131 case rclcpp::ParameterType::PARAMETER_STRING:
132 if (auto param_value = parameter.get_value<std::string>(); param_value.empty())
133 return tl::unexpected(
134 fmt::format("Parameter '{}' cannot be empty", parameter.get_name()));
135 break;
136 default:
137 if (auto param_value = parameter.get_value<std::vector<T>>(); param_value.empty())
138 return tl::unexpected(
139 fmt::format("Parameter '{}' cannot be empty", parameter.get_name()));
140 }
141 return {};
142}
143
150template <typename T>
151[[nodiscard]] auto element_bounds(rclcpp::Parameter const& parameter, T const& lower,
152 T const& upper) -> tl::expected<void, std::string> {
153 auto const& param_value = parameter.get_value<std::vector<T>>();
154 for (auto val : param_value)
155 if (val < lower || val > upper)
156 return tl::unexpected(
157 fmt::format("Value '{}' in parameter '{}' must be within bounds '[{}, {}]'", val,
158 parameter.get_name(), lower, upper));
159 return {};
160}
161
168template <typename T>
169[[nodiscard]] auto lower_element_bounds(rclcpp::Parameter const& parameter, T const& lower)
170 -> tl::expected<void, std::string> {
171 auto const& param_value = parameter.get_value<std::vector<T>>();
172 for (auto val : param_value)
173 if (val < lower)
174 return tl::unexpected(
175 fmt::format("Value '{}' in parameter '{}' must be above lower bound of '{}'", val,
176 parameter.get_name(), lower));
177 return {};
178}
179
186template <typename T>
187[[nodiscard]] auto upper_element_bounds(rclcpp::Parameter const& parameter, T const& upper)
188 -> tl::expected<void, std::string> {
189 auto const& param_value = parameter.get_value<std::vector<T>>();
190 for (auto val : param_value)
191 if (val > upper)
192 return tl::unexpected(
193 fmt::format("Value '{}' in parameter '{}' must be below upper bound of '{}'", val,
194 parameter.get_name(), upper));
195 return {};
196}
197
204template <typename T>
205[[nodiscard]] auto bounds(rclcpp::Parameter const& parameter, T const& lower, T const& upper)
206 -> tl::expected<void, std::string> {
207 auto const& param_value = parameter.get_value<T>();
208 if (param_value < lower || param_value > upper)
209 return tl::unexpected(
210 fmt::format("Parameter '{}' with the value '{}' must be within bounds '[{}, {}]'",
211 parameter.get_name(), param_value, lower, upper));
212 return {};
213}
214
221template <typename T>
222[[deprecated("Replace with rsl::gt_eq"), nodiscard]] auto lower_bounds(
223 rclcpp::Parameter const& parameter, T const& value) {
224 return detail::compare(parameter, value, "above lower bound of", std::greater_equal<T>());
225}
226
233template <typename T>
234[[deprecated("Replace with rsl::lt_eq"), nodiscard]] auto upper_bounds(
235 rclcpp::Parameter const& parameter, T const& value) {
236 return detail::compare(parameter, value, "below upper bound of", std::less_equal<T>());
237}
238
245template <typename T>
246[[nodiscard]] auto lt(rclcpp::Parameter const& parameter, T const& value) {
247 return detail::compare(parameter, value, "less than", std::less<T>());
248}
249
256template <typename T>
257[[nodiscard]] auto gt(rclcpp::Parameter const& parameter, T const& value) {
258 return detail::compare(parameter, value, "greater than", std::greater<T>());
259}
260
267template <typename T>
268[[nodiscard]] auto lt_eq(rclcpp::Parameter const& parameter, T const& value) {
269 return detail::compare(parameter, value, "less than or equal to", std::less_equal<T>());
270}
271
278template <typename T>
279[[nodiscard]] auto gt_eq(rclcpp::Parameter const& parameter, T const& value) {
280 return detail::compare(parameter, value, "greater than or equal to", std::greater_equal<T>());
281}
282
289template <typename T>
290[[nodiscard]] auto one_of(rclcpp::Parameter const& parameter, std::vector<T> const& collection)
291 -> tl::expected<void, std::string> {
292 auto const& param_value = parameter.get_value<T>();
293 if (contains(collection, param_value)) return {};
294 return tl::unexpected(fmt::format(
295 "Parameter '{}' with the value '{}' is not in the set '{{{}}}'", parameter.get_name(),
296 param_value, fmt::format("{}", fmt::join(collection, ", "))));
297}
298
302[[nodiscard]] RSL_EXPORT auto to_parameter_result_msg(tl::expected<void, std::string> const& result)
303 -> rcl_interfaces::msg::SetParametersResult;
304
305} // namespace rsl
auto contains(Collection const &collection, typename Collection::const_reference value)
Determine if a collection contains a value. Example usage:
Definition algorithm.hpp:19
auto is_unique(Collection collection)
Determine if all elements in a collection are unique. Example usage:
Definition algorithm.hpp:37
auto fixed_size(rclcpp::Parameter const &parameter, size_t const size)
Is the array size of parameter equal to passed in size?
Definition parameter_validators.hpp:94
auto lower_element_bounds(rclcpp::Parameter const &parameter, T const &lower) -> tl::expected< void, std::string >
Are all elements of parameter greater than lower bound?
Definition parameter_validators.hpp:169
auto bounds(rclcpp::Parameter const &parameter, T const &lower, T const &upper) -> tl::expected< void, std::string >
Is parameter within bounds (inclusive)?
Definition parameter_validators.hpp:205
auto gt_eq(rclcpp::Parameter const &parameter, T const &value)
Is parameter greater than or equal to some value?
Definition parameter_validators.hpp:279
auto subset_of(rclcpp::Parameter const &parameter, std::vector< T > const &valid_values) -> tl::expected< void, std::string >
Are the values in parameter a subset of the valid values?
Definition parameter_validators.hpp:76
auto unique(rclcpp::Parameter const &parameter) -> tl::expected< void, std::string >
Is every element of rclcpp::Parameter unique?
Definition parameter_validators.hpp:63
auto one_of(rclcpp::Parameter const &parameter, std::vector< T > const &collection) -> tl::expected< void, std::string >
Is the parameter value one of a set of values?
Definition parameter_validators.hpp:290
auto size_lt(rclcpp::Parameter const &parameter, size_t const size)
Is the array size of parameter less than passed in size?
Definition parameter_validators.hpp:116
auto upper_element_bounds(rclcpp::Parameter const &parameter, T const &upper) -> tl::expected< void, std::string >
Are all elements of parameter less than some upper bound?
Definition parameter_validators.hpp:187
auto element_bounds(rclcpp::Parameter const &parameter, T const &lower, T const &upper) -> tl::expected< void, std::string >
Are all elements of parameter within the bounds (inclusive)?
Definition parameter_validators.hpp:151
auto not_empty(rclcpp::Parameter const &parameter) -> tl::expected< void, std::string >
Is the size of the value passed in not zero?
Definition parameter_validators.hpp:128
RSL_EXPORT auto to_parameter_result_msg(tl::expected< void, std::string > const &result) -> rcl_interfaces::msg::SetParametersResult
Convert the result of a validator function into a SetParametersResult msg.
auto lower_bounds(rclcpp::Parameter const &parameter, T const &value)
Is parameter within some lower bound (same as gt_eq)?
Definition parameter_validators.hpp:222
auto lt(rclcpp::Parameter const &parameter, T const &value)
Is parameter less than some value?
Definition parameter_validators.hpp:246
auto size_gt(rclcpp::Parameter const &parameter, size_t const size)
Is the array size of parameter greater than passed in size?
Definition parameter_validators.hpp:105
auto gt(rclcpp::Parameter const &parameter, T const &value)
Is parameter greater than some value?
Definition parameter_validators.hpp:257
auto lt_eq(rclcpp::Parameter const &parameter, T const &value)
Is parameter less than or equal to some value?
Definition parameter_validators.hpp:268
auto upper_bounds(rclcpp::Parameter const &parameter, T const &value)
Is parameter within some upper bound (same as lt_eq)?
Definition parameter_validators.hpp:234