29 #include <initializer_list>
33 #include <type_traits>
38 #include <fable/utility/templates.hpp>
40 namespace fable::schema {
43 Number<T> Number<T>::minimum(T value) && {
45 exclusive_min_ =
false;
46 return std::move(*
this);
50 Number<T> Number<T>::exclusive_minimum(T value) && {
52 exclusive_min_ =
true;
53 return std::move(*
this);
57 Number<T> Number<T>::maximum(T value) && {
59 exclusive_max_ =
false;
60 return std::move(*
this);
64 Number<T> Number<T>::exclusive_maximum(T value) && {
66 exclusive_max_ =
true;
67 return std::move(*
this);
71 std::pair<T, T> Number<T>::bounds()
const {
72 return std::make_pair(value_min_, value_max_);
76 Number<T> Number<T>::bounds(T min, T max) && {
77 exclusive_min_ =
false;
79 exclusive_max_ =
false;
81 return std::move(*
this);
85 Number<T> Number<T>::bounds_with(T min, T max, std::initializer_list<T> whitelisted) && {
86 exclusive_min_ =
false;
88 exclusive_max_ =
false;
90 for (
auto x : whitelisted) {
93 return std::move(*
this);
97 Number<T> Number<T>::whitelist(T x) && {
99 return std::move(*
this);
102 template <
typename T>
103 Number<T> Number<T>::whitelist(std::initializer_list<T> xs) && {
107 return std::move(*
this);
110 template <
typename T>
111 void Number<T>::insert_whitelist(T x) {
112 if (std::is_floating_point_v<T>) {
113 throw std::logic_error(
"cannot whitelist floating-point numbers");
115 if (blacklist_.count(x)) {
116 throw std::logic_error(
"cannot add blacklisted value to whitelist: " + std::to_string(x));
118 whitelist_.insert(x);
121 template <
typename T>
122 Number<T> Number<T>::blacklist(T x) && {
124 return std::move(*
this);
127 template <
typename T>
128 Number<T> Number<T>::blacklist(std::initializer_list<T> xs) && {
132 return std::move(*
this);
135 template <
typename T>
136 void Number<T>::insert_blacklist(T x) {
137 if (std::is_floating_point_v<T>) {
138 throw std::logic_error(
"cannot blacklist floating-point numbers");
140 if (blacklist_.count(x)) {
141 throw std::logic_error(
"cannot add whitelisted value to blacklist: " + std::to_string(x));
143 blacklist_.insert(x);
146 template <
typename T>
149 {
"type", this->type_string()},
150 {exclusive_min_ ?
"exclusiveMinimum" :
"minimum", value_min_},
151 {exclusive_max_ ?
"exclusiveMaximum" :
"maximum", value_max_},
154 if (!std::is_floating_point_v<T>) {
155 auto write_list = [&j](
auto name,
auto xlist) {
156 if (!xlist.empty()) {
158 for (
auto x : xlist) {
165 write_list(
"whitelist", whitelist_);
166 write_list(
"blacklist", blacklist_);
169 this->augment_schema(j);
173 template <
typename T>
176 case JsonType::number_unsigned:
177 return validate_bounds<uint64_t>(c, err);
178 case JsonType::number_integer:
179 return validate_bounds<int64_t>(c, err);
180 case JsonType::number_float:
181 if (this->type() != JsonType::number_float) {
182 return this->set_wrong_type(err, c);
184 return validate_bounds<double>(c, err);
187 return this->set_wrong_type(err, c);
191 template <
typename T>
193 assert(ptr_ !=
nullptr);
194 j = serialize(*ptr_);
197 template <
typename T>
199 assert(ptr_ !=
nullptr);
200 *ptr_ = deserialize(c);
203 template <
typename T>
208 template <
typename T>
209 T Number<T>::deserialize(
const Conf& c)
const {
213 template <
typename T>
214 void Number<T>::serialize_into(Json& j,
const T& x)
const {
218 template <
typename T>
219 void Number<T>::deserialize_into(
const Conf& c, T& x)
const {
223 template <
typename T>
241 template <
typename T>
242 template <
typename B>
244 auto original = c.
get<B>();
245 auto value =
static_cast<T
>(original);
246 if constexpr (!std::is_floating_point_v<T>) {
247 if (!is_cast_safe<T>(original)) {
248 return this->set_error(err, c,
249 "failed to convert input to destination type {}, got {}( {} ) = {}",
255 if (!std::is_floating_point_v<T>) {
256 if (whitelist_.count(value)) {
259 if (blacklist_.count(value)) {
260 return this->set_error(err, c,
"unexpected blacklisted value {}", value);
265 if (exclusive_min_) {
266 if (value <= value_min_) {
267 return this->set_error(err, c,
"expected exclusive minimum of {}, got {}", value_min_, value);
270 if (value < value_min_) {
271 return this->set_error(err, c,
"expected minimum of {}, got {}", value_min_, value);
275 if (exclusive_max_) {
276 if (value >= value_max_) {
277 return this->set_error(err, c,
"expected exclusive maximum of {}, got {}", value_max_, value);
280 if (value > value_max_) {
281 return this->set_error(err, c,
"expected maximum of {}, got {}", value_max_, value);
T get() const
Definition: conf.hpp:166
Definition: number.hpp:36
void from_conf(const Conf &c) override
Definition: number_impl.hpp:198
virtual Json to_json() const
Definition: interface.hpp:254
Json json_schema() const override
Definition: number_impl.hpp:147
void reset_ptr() override
Definition: number_impl.hpp:224
bool validate(const Conf &c, std::optional< SchemaError > &err) const override
Definition: number_impl.hpp:174
nlohmann::json Json
Definition: fable_fwd.hpp:35
Definition: templates.hpp:66