libkazv
Loading...
Searching...
No Matches
validator.hpp
Go to the documentation of this file.
1/*
2 * This file is part of libkazv.
3 * SPDX-FileCopyrightText: 2020-2023 tusooa <tusooa@kazv.moe>
4 * SPDX-License-Identifier: AGPL-3.0-or-later
5 */
6
7#pragma once
8#include <libkazv-config.hpp>
9
10#include <functional>
11
12#include <types.hpp>
13
14namespace Kazv
15{
60 template<class Jsonish, class Key, class Validator>
61 bool cast(Jsonish &ret, const Jsonish &input, Key &&k, Validator &&f)
62 {
63 if (!input.contains(k)) {
64 return false;
65 }
66 auto [res, output] = std::invoke(std::forward<Validator>(f), input[k]);
67 if (!res) {
68 return false;
69 }
70 ret[k] = output;
71 return true;
72 }
73
84 template<class Func>
85 auto identValidate(Func &&f)
86 {
87 return [f=std::forward<Func>(f)](auto &&val) mutable {
88 auto res = std::invoke(std::forward<Func>(f), val);
89 return std::pair<bool, json>(res, std::forward<decltype(val)>(val));
90 };
91 }
92
97 {
101 FailAll,
102 };
103
153 template<class Jsonish, class Key, class Validator>
154 bool castArray(Jsonish &ret, const Jsonish &input, Key &&k, Validator &&f, CastArrayStrategy strategy)
155 {
156 using JsonT = std::decay_t<Jsonish>;
157
158 if (!(input.contains(k) && input[k].is_array())) {
159 return false;
160 }
161
162 auto array = JsonT::array();
163
164 for (const auto &inputItem : input[k]) {
165 auto [res, outputItem] = std::invoke(f, inputItem);
166 if (!res) {
167 if (strategy == CastArrayStrategy::FailAll) {
168 return false;
169 }
170 } else {
171 array.push_back(std::move(outputItem));
172 }
173 }
174
175 ret[k] = std::move(array);
176
177 return true;
178 }
179
184 {
188 FailAll,
189 };
190
244 template<class Jsonish, class Key, class Validator>
245 bool castObject(Jsonish &ret, const Jsonish &input, Key &&k, Validator &&f, CastObjectStrategy strategy)
246 {
247 using JsonT = std::decay_t<Jsonish>;
248
249 if (!(input.contains(k) && input[k].is_object())) {
250 return false;
251 }
252
253 auto obj = JsonT::object();
254
255 for (const auto &[inputKey, inputValue] : input[k].items()) {
256 auto inputItem = JsonT::array({JsonT(inputKey), inputValue});
257 auto [res, outputItem] = std::invoke(f, inputItem);
258 if (!res) {
259 if (strategy == CastObjectStrategy::FailAll) {
260 return false;
261 }
262 } else {
263 auto outputKey = outputItem[0];
264 auto outputValue = std::move(outputItem)[1];
265 obj[std::move(outputKey)] = std::move(outputValue);
266 }
267 }
268
269 ret[k] = std::move(obj);
270
271 return true;
272 }
273
286 template<class Jsonish, class Key, class Jsonish2>
287 std::decay_t<Jsonish> makeDefaultValue(Jsonish &&input, Key &&k, Jsonish2 &&defaultValue)
288 {
289 using JsonT = std::decay_t<Jsonish>;
290
291 if (input.contains(k)) {
292 return std::forward<Jsonish>(input);
293 } else {
294 JsonT output = std::forward<Jsonish>(input);
295 output[std::forward<Key>(k)] = std::forward<Jsonish2>(defaultValue);
296 return output;
297 }
298 }
299}
Definition location.hpp:10
bool castObject(Jsonish &ret, const Jsonish &input, Key &&k, Validator &&f, CastObjectStrategy strategy)
Cast an object of items.
Definition validator.hpp:245
bool castArray(Jsonish &ret, const Jsonish &input, Key &&k, Validator &&f, CastArrayStrategy strategy)
Cast an array of items.
Definition validator.hpp:154
CastObjectStrategy
Strategy used for castObject().
Definition validator.hpp:184
@ FailAll
If any item is invalid, fail the entire cast.
std::decay_t< Jsonish > makeDefaultValue(Jsonish &&input, Key &&k, Jsonish2 &&defaultValue)
Replace a non-existent value with a default one.
Definition validator.hpp:287
bool cast(Jsonish &ret, const Jsonish &input, Key &&k, Validator &&f)
Run validator against input[k] and add it to ret.
Definition validator.hpp:61
CastArrayStrategy
Strategy used for castArray().
Definition validator.hpp:97
@ IgnoreInvalid
If any item is invalid, ignore them and add all valid entries into the output.
@ FailAll
If any item is invalid, fail the entire cast.
auto identValidate(Func &&f)
Make an identity validator.
Definition validator.hpp:85