9#include "json_helpers.h"
16 auto parse(std::string_view
wilson_str) -> nlohmann::json;
18 auto parse_array(std::string_view
wilson_str) -> nlohmann::json;
31 auto consume_value(std::string_view&
wilson_str) -> nlohmann::json;
33 template <
typename OUTFUNC>
34 void output(
OUTFUNC&&
out, nlohmann::json
const& value);
36 inline void output_to_stream(std::ostream&
strm, nlohmann::json
const& value)
38 output([&](std::string_view
val) {
strm.write(
val.data(),
val.size()); }, value);
41 std::string to_string(nlohmann::json
const& value);
43 nlohmann::json load_file(std::filesystem::path
const& from, std::error_code&
ec);
44 nlohmann::json try_load_file(std::filesystem::path
const& from, nlohmann::json
const&
or_json = json::empty_json);
49 inline nlohmann::json consume_array(std::string_view& str,
char closing_char)
51 auto obj = nlohmann::json::array();
54 string_ops::trim_whitespace_left(str);
58 obj.push_back(wilson::consume_value(str));
60 string_ops::trim_whitespace_left(str);
62 if (!str.empty() && (str[0] ==
',' || str[0] ==
';'))
65 }
while (!str.empty());
72 std::pair<std::string_view, std::string> result;
74 result = parsing::consume_c_string<'\''>(
_str);
76 result = parsing::consume_c_string<
'"'>(
_str);
77 return std::move(result).second;
83 string_ops::trim_whitespace_left(str);
84 const auto first = str[0];
87 else if (string_ops::ascii::isidentstart(
first))
96 if (string_ops::ascii::isalpha(str[0]))
101 else if (
string ==
"false")
103 else if (
string ==
"null" ||
string ==
"nil")
113 inline nlohmann::json consume_object(std::string_view& str,
char closing_char)
115 auto obj = nlohmann::json::object();
119 string_ops::trim_whitespace_left(str);
124 string_ops::trim_whitespace_left(str);
128 obj[std::move(
key)] =
true;
132 if (str[0] ==
',' || str[0] ==
';')
134 obj[std::move(
key)] =
true;
138 if (str[0] ==
'=' || str[0] ==
':')
139 str.remove_prefix(1);
141 string_ops::trim_whitespace_left(str);
143 auto val = wilson::consume_value(str);
147 string_ops::trim_whitespace_left(str);
149 if (!str.empty() && (str[0] ==
',' || str[0] ==
';'))
150 str.remove_prefix(1);
151 }
while (!str.empty());
158 string_ops::trim_whitespace_left(str);
159 if (str.empty())
return {};
161 const auto first = str[0];
163 return consume_object(str);
165 return consume_array(str,
')');
167 return consume_array(str,
']');
168 else if (string_ops::ascii::isidentstart(
first) ||
first ==
'\'' ||
first ==
'"')
170 else if (string_ops::ascii::isdigit(
first) ||
first ==
'-')
176 str = string_ops::make_sv(
fcresult.ptr, str.end());
184 inline auto parse(std::string_view
wilson_str) -> nlohmann::json
195 inline auto parse_array(std::string_view
wilson_str) -> nlohmann::json
217 template <
typename OUTFUNC,
typename VAL>
225 template <
typename OUTFUNC>
231 auto start =
strval.begin();
234 if (string_ops::ascii::isprint(*
it) && *
it !=
'"' && *
it !=
'\\')
239 func(string_ops::make_sv(start,
it));
242 auto&& [end,
ec] = std::to_chars(std::begin(
temp), std::end(
temp),
static_cast<uint8_t>(*
it), 16);
243 func(string_ops::make_sv(std::begin(
temp), end));
245 start = std::next(
it);
248 if (start !=
strval.end())
249 func(string_ops::make_sv(start,
strval.end()));
254 template <
typename OUTFUNC>
255 void output(
OUTFUNC&&
out, nlohmann::json
const& value)
257 switch (value.type())
259 using enum nlohmann::detail::value_t;
260 case null:
out(
"null");
return;
265 wilson::detail::output_string(
out,
k);
267 wilson::output(
out, v);
281 case string: wilson::detail::output_string(
out, value.get_ref<nlohmann::json::string_t
const&>());
return;
282 case boolean:
out(value.get_ref<nlohmann::json::boolean_t
const&>() ?
"true" :
"false");
return;
283 case number_integer: wilson::detail::output_value(
out, value.get_ref<nlohmann::json::number_integer_t
const&>());
return;
284 case number_unsigned: wilson::detail::output_value(
out, value.get_ref<nlohmann::json::number_unsigned_t
const&>());
return;
285 case number_float: wilson::detail::output_value(
out, value.get_ref<nlohmann::json::number_float_t
const&>());
return;
290 wilson::detail::output_value(
out,
byte);
299 inline std::string to_string(nlohmann::json
const& value)
302 wilson::output([&](std::string_view
val) { result +=
val; }, value);
306 inline nlohmann::json
load_file(std::filesystem::path
const& from, std::error_code&
ec)
309 return ec ? nlohmann::json{} : wilson::parse(std::string_view{ source.begin(), source.end() });
312 inline nlohmann::json
try_load_file(std::filesystem::path
const& from, nlohmann::json
const&
or_json)
316 return ec ?
or_json : wilson::parse(std::string_view{ source.begin(), source.end() });
constexpr auto bit_count
Equal to the number of bits in the type.
std::string_view consume_while(std::string_view &str, FUNC &&pred)
Consumes characters from the beginning of str while they match pred(str[0]).
auto from_chars(std::string_view str, T &value, const int base=10) noexcept
A version of std::from_chars that takes a std::string_view as the first argument.
char consume(std::string_view &str)
Consumes and returns the first character in the str, or \0 if no more characters.
std::string load_file(std::filesystem::path const &from, std::error_code &ec)
Returns the contents of a text file as a string.
expected< std::string, std::error_code > try_load_file(std::filesystem::path const &from)
Returns the contents of a text file as a string.
The below code is based on Sun's libm library code, which is licensed under the following license: