Clio  develop
The XRP Ledger API server.
Loading...
Searching...
No Matches
Modifiers.hpp
1#pragma once
2
3#include "rpc/Errors.hpp"
4#include "rpc/common/Types.hpp"
5#include "util/JsonUtils.hpp"
6
7#include <boost/json/value.hpp>
8#include <boost/json/value_to.hpp>
9#include <xrpl/protocol/ErrorCodes.h>
10
11#include <concepts>
12#include <exception>
13#include <functional>
14#include <string>
15#include <string_view>
16
17namespace rpc::modifiers {
18
22template <typename Type>
23class Clamp final {
24 Type min_;
25 Type max_;
26
27public:
34 explicit Clamp(Type min, Type max) : min_{min}, max_{max}
35 {
36 }
37
45 [[nodiscard]] MaybeError
46 modify(boost::json::value& value, std::string_view key) const
47 {
48 using boost::json::value_to;
49
50 if (not value.is_object() or not value.as_object().contains(key))
51 return {}; // ignore. field does not exist, let 'required' fail instead
52
53 // clamp to min_ and max_
54 auto const oldValue = value_to<Type>(value.as_object().at(key));
55 value.as_object()[key] = std::clamp<Type>(oldValue, min_, max_);
56
57 return {};
58 }
59};
60
66struct ToLower final {
74 [[nodiscard]] static MaybeError
75 modify(boost::json::value& value, std::string_view key)
76 {
77 if (not value.is_object() or not value.as_object().contains(key))
78 return {}; // ignore. field does not exist, let 'required' fail instead
79
80 if (not value.as_object().at(key).is_string())
81 return {}; // ignore for non-string types
82
83 value.as_object()[key] =
84 util::toLower(boost::json::value_to<std::string>(value.as_object().at(key)));
85 return {};
86 }
87};
88
94struct ToNumber final {
102 [[nodiscard]] static MaybeError
103 modify(boost::json::value& value, std::string_view key)
104 {
105 if (not value.is_object() or not value.as_object().contains(key))
106 return {}; // ignore. field does not exist, let 'required' fail instead
107
108 if (not value.as_object().at(key).is_string())
109 return {}; // ignore for non-string types
110
111 auto const strInt = boost::json::value_to<std::string>(value.as_object().at(key));
112 if (strInt.find('.') != std::string::npos)
113 return Error{Status{RippledError::rpcINVALID_PARAMS}}; // maybe a float
114
115 try {
116 value.as_object()[key] = std::stoi(strInt);
117 } catch (std::exception& e) {
118 return Error{Status{RippledError::rpcINVALID_PARAMS}};
119 }
120 return {};
121 }
122};
123
127class CustomModifier final {
128 std::function<MaybeError(boost::json::value&, std::string_view)> modifier_;
129
130public:
137 template <typename Fn>
138 requires std::invocable<Fn, boost::json::value&, std::string_view>
139 explicit CustomModifier(Fn&& fn) : modifier_{std::forward<Fn>(fn)}
140 {
141 }
142
151 [[nodiscard]] MaybeError
152 modify(boost::json::value& value, std::string_view key) const
153 {
154 if (not value.is_object() or not value.as_object().contains(key))
155 return {}; // ignore. field does not exist, let 'required' fail instead
156
157 return modifier_(value.as_object().at(key), key);
158 };
159};
160
161} // namespace rpc::modifiers
MaybeError modify(boost::json::value &value, std::string_view key) const
Clamp the value to stored min and max values.
Definition Modifiers.hpp:46
Clamp(Type min, Type max)
Construct the modifier storing min and max values.
Definition Modifiers.hpp:34
CustomModifier(Fn &&fn)
Constructs a custom modifier from any supported callable.
Definition Modifiers.hpp:139
MaybeError modify(boost::json::value &value, std::string_view key) const
Modify the JSON value according to the custom modifier function stored.
Definition Modifiers.hpp:152
std::expected< void, Status > MaybeError
Return type used for Validators that can return error but don't have specific value to return.
Definition Types.hpp:36
std::unexpected< Status > Error
The type that represents just the error part of MaybeError.
Definition Types.hpp:56
std::string toLower(std::string str)
Convert a string to lowercase.
Definition JsonUtils.hpp:29
A status returned from any RPC handler.
Definition Errors.hpp:65
Convert input string to lower case.
Definition Modifiers.hpp:66
static MaybeError modify(boost::json::value &value, std::string_view key)
Update the input string to lower case.
Definition Modifiers.hpp:75
Convert input string to integer.
Definition Modifiers.hpp:94
static MaybeError modify(boost::json::value &value, std::string_view key)
Update the input string to integer if it can be converted to integer by stoi.
Definition Modifiers.hpp:103