4#include <rsl/export.hpp>
8#include <rcl_interfaces/msg/set_parameters_result.hpp>
9#include <rclcpp/parameter.hpp>
10#include <tl_expected/expected.hpp>
12#include <fmt/ranges.h>
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));
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));
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,
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()));
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)
81 return tl::unexpected(
82 fmt::format(
"Entry '{}' in parameter '{}' is not in the set '{{{}}}'", value,
83 parameter.get_name(), fmt::join(valid_values,
", ")));
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<>());
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<>());
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<>());
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()));
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()));
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));
170 -> tl::expected<void, std::string> {
171 auto const& param_value = parameter.get_value<std::vector<T>>();
172 for (
auto val : param_value)
174 return tl::unexpected(
175 fmt::format(
"Value '{}' in parameter '{}' must be above lower bound of '{}'", val,
176 parameter.get_name(), lower));
188 -> tl::expected<void, std::string> {
189 auto const& param_value = parameter.get_value<std::vector<T>>();
190 for (
auto val : param_value)
192 return tl::unexpected(
193 fmt::format(
"Value '{}' in parameter '{}' must be below upper bound of '{}'", val,
194 parameter.get_name(), upper));
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));
223 rclcpp::Parameter
const& parameter, T
const& value) {
224 return detail::compare(parameter, value,
"above lower bound of", std::greater_equal<T>());
235 rclcpp::Parameter
const& parameter, T
const& value) {
236 return detail::compare(parameter, value,
"below upper bound of", std::less_equal<T>());
246[[nodiscard]]
auto lt(rclcpp::Parameter
const& parameter, T
const& value) {
247 return detail::compare(parameter, value,
"less than", std::less<T>());
257[[nodiscard]]
auto gt(rclcpp::Parameter
const& parameter, T
const& value) {
258 return detail::compare(parameter, value,
"greater than", std::greater<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>());
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>());
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,
", "))));
303 -> rcl_interfaces::msg::SetParametersResult;
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 ¶meter, 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 ¶meter, 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 ¶meter, 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 ¶meter, T const &value)
Is parameter greater than or equal to some value?
Definition parameter_validators.hpp:279
auto subset_of(rclcpp::Parameter const ¶meter, 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 ¶meter) -> tl::expected< void, std::string >
Is every element of rclcpp::Parameter unique?
Definition parameter_validators.hpp:63
auto one_of(rclcpp::Parameter const ¶meter, 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 ¶meter, 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 ¶meter, 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 ¶meter, 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 ¶meter) -> 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 ¶meter, T const &value)
Is parameter within some lower bound (same as gt_eq)?
Definition parameter_validators.hpp:222
auto lt(rclcpp::Parameter const ¶meter, T const &value)
Is parameter less than some value?
Definition parameter_validators.hpp:246
auto size_gt(rclcpp::Parameter const ¶meter, 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 ¶meter, T const &value)
Is parameter greater than some value?
Definition parameter_validators.hpp:257
auto lt_eq(rclcpp::Parameter const ¶meter, T const &value)
Is parameter less than or equal to some value?
Definition parameter_validators.hpp:268
auto upper_bounds(rclcpp::Parameter const ¶meter, T const &value)
Is parameter within some upper bound (same as lt_eq)?
Definition parameter_validators.hpp:234