20#include <initializer_list>
38 static int compare(
const value& a, std::string_view b)
40 return compare_text(a, b);
45struct enum_text_order_icase
48 static int compare(
const value& a, std::string_view b)
50 return compare_text_icase(a, b);
58template <
typename FValueComp,
typename TTextOrder>
61 using is_transparent = void;
64 bool operator()(
const value& a,
const value& b)
const
66 return FValueComp()(a, b);
70 bool operator()(
const value& a, std::string_view b)
const
72 return TTextOrder::compare(a, b) < 0;
76 bool operator()(std::string_view a,
const value& b)
const
79 return TTextOrder::compare(b, a) > 0;
87template <
typename FValueComp>
88struct enum_value_order
90 using type = FValueComp;
92 static constexpr bool reads_text =
false;
96struct enum_value_order<
std::less<value>>
98 using type = enum_value_less<std::less<value>, enum_text_order>;
100 static constexpr bool reads_text =
true;
104struct enum_value_order<value_less>
106 using type = enum_value_less<value_less, enum_text_order>;
108 static constexpr bool reads_text =
true;
112struct enum_value_order<value_less_icase>
114 using type = enum_value_less<value_less_icase, enum_text_order_icase>;
116 static constexpr bool reads_text =
true;
145template <
typename TEnum,
146 typename FEnumComp = std::less<TEnum>,
147 typename FValueComp = std::less<value>
156 template <
typename TForwardIterator>
157 explicit enum_adapter(std::string enum_name, TForwardIterator first, TForwardIterator last) :
158 _enum_name(
std::move(enum_name))
160 for (
auto iter = first; iter != last; ++iter)
162 _val_to_cpp.insert({ iter->second, iter->first });
163 _cpp_to_val.insert(*iter);
190 explicit enum_adapter(std::string enum_name, std::initializer_list<std::pair<TEnum, value>> mapping) :
200 return settle(
context, from, *lent);
202 if constexpr (value_order::reads_text)
212 return settle(
context, from, std::string_view(decoded));
226 auto iter = _cpp_to_val.find(from);
227 if (iter != end(_cpp_to_val))
234 using value_order = detail::enum_value_order<FValueComp>;
237 template <
typename TKey>
238 std::expected<TEnum, ast_node_type> settle(extraction_context& context, reader& from,
const TKey& key)
const
240 auto iter = _val_to_cpp.find(key);
241 if (iter == _val_to_cpp.end())
246 return context.problem(context.problem_path(from), describe_miss(value(key)));
251 TEnum out = iter->second;
252 (void) from.next_value();
259 context.note_value_consumed(from);
265 std::string describe_miss(
const value& found)
const
267 std::string message =
"Invalid value for " + _enum_name +
": " +
to_string(found);
268 if (!_val_to_cpp.empty())
270 const char* separator =
" (expected one of ";
271 for (
const auto& accepted : _val_to_cpp)
273 message += separator;
283 std::string _enum_name;
284 std::map<value, TEnum, typename value_order::type> _val_to_cpp;
285 std::map<TEnum, value, FEnumComp> _cpp_to_val;
291template <
typename TEnum,
typename FEnumComp = std::less<TEnum>>
Copyright (c) 2015-2026 by Travis Gockel.
Utilities for directly dealing with a JSON AST.
An adapter for the type T.
const T & as() const
Get the underlying data of this node as T.
Provides extra information to routines used for extraction and serialization.
An adapter for enumeration types.
virtual std::expected< TEnum, ast_node_type > create(extraction_context &context, reader &from) const override
Create an instance of T by reading from.
enum_adapter(std::string enum_name, TForwardIterator first, TForwardIterator last)
Create an adapter with mapping values from the range [first, last).
enum_adapter(std::string enum_name, std::initializer_list< std::pair< TEnum, value > > mapping)
Create an adapter with the specified mapping values.
A reader instance reads from some form of JSON source (probably a string) and converts it into a JSON...
ast_node_type current_type() const
Get the type of the current AST node, which is always current().type().
const ast_node & current() const
Get the current AST node this reader is pointing at.
optional< const value & > current_value() const noexcept
Get the in-memory value this reader is positioned on, if it has one to lend.
bool good() const
Check if this reader is still good to read from.
Represents a single JSON value, which can be any one of a potential kind, each behaving slightly diff...
Copyright (c) 2014-2020 by Travis Gockel.
A collection of function objects a la <functional>.
int compare(const value &a, const value &b, const TCompareTraits &traits)
Compare the values a and b using the comparison traits.
#define JSONV_NODISCARD
Warn if the caller discards the result of this function.
JSONV_PUBLIC std::string to_string(const ast_node_type &type)
Get what operator<< writes for type as a std::string.
JSONV_PUBLIC const value null
An instance with kind::null.
Conversion between C++ types and JSON values.