7#include <nlohmann/json.hpp>
24 inline std::string
load_file(std::filesystem::path
const& from, std::error_code&
ec)
27 return ec ? std::string{} : std::string{ source.begin(), source.end() };
32 inline std::string
load_file(std::filesystem::path
const& from)
37 throw std::runtime_error(format(
"file '{}' not found", from.string()));
38 return std::string{ source.begin(), source.end() };
49 inline bool save_file(std::filesystem::path
const&
to, std::string_view
string, std::error_code&
ec)
52 std::ofstream
out{
to };
53 out.write(
string.data(),
string.size());
57 inline void save_file(std::filesystem::path
const&
to, std::string_view
string)
59 std::ofstream
out{
to };
60 out.exceptions(std::ios::badbit | std::ios::failbit);
61 out.write(
string.data(),
string.size());
74 inline std::vector<std::string>
load_file(std::filesystem::path
const& from, std::error_code&
ec)
80 std::vector<std::string> result;
85 inline std::vector<std::string>
load_file(std::filesystem::path
const& from)
90 throw std::runtime_error(format(
"file '{}' not found", from.string()));
92 std::vector<std::string> result;
97 template <
typename CALLBACK>
98 requires std::invocable<CALLBACK, std::string_view>
104 throw std::runtime_error(format(
"file '{}' not found", from.string()));
106 std::vector<std::string> result;
111 inline std::vector<std::string>
try_load_file(std::filesystem::path
const& from)
117 template <std::ranges::range T>
118 inline bool save_file(std::filesystem::path
const&
to, T
string_range, std::error_code&
ec)
121 std::ofstream
out{
to };
124 out.write(std::to_address(std::ranges::begin(
string)), std::ranges::size(
string));
130 template <std::ranges::range T>
131 inline void save_file(std::filesystem::path
const&
to, T
string_range)
133 std::ofstream
out{
to };
134 out.exceptions(std::ios::badbit | std::ios::failbit);
137 out.write(std::to_address(std::ranges::begin(
string)), std::ranges::size(
string));
150 inline const nlohmann::json empty_json = nlohmann::json{};
151 inline const nlohmann::json empty_json_array = nlohmann::json::array();
152 inline const nlohmann::json empty_json_object = nlohmann::json::object();
154 inline nlohmann::json
load_file(std::filesystem::path
const& from, std::error_code&
ec)
157 return ec ? nlohmann::json{} : nlohmann::json::parse(source);
160 inline nlohmann::json
try_load_file(std::filesystem::path
const& from, nlohmann::json
const&
or_json = empty_json)
164 return ec ?
or_json : nlohmann::json::parse(source);
167 inline nlohmann::json
load_file(std::filesystem::path
const& from)
175 std::throw_with_nested(std::runtime_error{ format(
"while trying to load json file {}", from.string()) });
179 inline void save_file(std::filesystem::path
const&
to, nlohmann::json
const&
j,
bool pretty =
true)
181 std::ofstream
out{
to };
182 nlohmann::detail::serializer<nlohmann::json>
s{ nlohmann::detail::output_adapter<char, std::string>(
out),
'\t', nlohmann::detail::error_handler_t::strict };
187 using jtype = nlohmann::json::value_t;
191 inline nlohmann::json
const&
get(nlohmann::json
const&
g, std::string_view
key,
jtype type = jtype::discarded)
193 if (
auto it =
g.find(
key);
it !=
g.end() && (type == jtype::discarded ||
it->type() == type))
195 return json::empty_json;
200 inline std::string
get(nlohmann::json
const&
g, std::string_view
key, std::string_view default_value,
jtype type = jtype::discarded)
202 if (
auto it =
g.find(
key);
it !=
g.end() && (type == jtype::discarded ||
it->type() == type))
203 return (std::string)*
it;
204 return std::string{ default_value };
209 template <std::
integral T>
210 inline T
get(nlohmann::json
const&
g, std::string_view
key, T default_value,
jtype type = jtype::discarded)
212 if (
auto it =
g.find(
key);
it !=
g.end() && (type == jtype::discarded ||
it->type() == type))
214 return default_value;
219 template <std::
floating_po
int T>
220 inline T
get(nlohmann::json
const&
g, std::string_view
key, T default_value,
jtype type = jtype::discarded)
222 if (
auto it =
g.find(
key);
it !=
g.end() && (type == jtype::discarded ||
it->type() == type))
224 return default_value;
228 inline nlohmann::json
const&
get_array(nlohmann::json
const&
g, std::string_view
key)
230 if (
auto it =
g.find(
key);
it !=
g.end() &&
it->type() == jtype::array)
232 return json::empty_json_array;
237 template <
typename T>
238 inline void field(T&
val, nlohmann::json
const&
g, std::string_view
key)
251 std::throw_with_nested(std::runtime_error{ std::format(
"while trying to convert value at key \"{}\" to type {}",
key,
typeid(T).name()) });
254 throw std::runtime_error(std::format(
"no key \"{}\" found",
key));
259 template <
typename T>
269 std::throw_with_nested(std::runtime_error{ std::format(
"while trying to convert value at element {} to type {}",
key,
typeid(T).name()) });
275 template <
typename T>
289 std::throw_with_nested(std::runtime_error{ std::format(
"while trying to convert value at key \"{}\" to type {}",
key,
typeid(T).name()) });
295 template <
typename VISIT_FUNC>
300 using enum nlohmann::detail::value_t;
301 case object:
return func(
j.get_ref<nlohmann::json::object_t
const&>());
302 case array:
return func(
j.get_ref<nlohmann::json::array_t
const&>());
303 case string:
return func(
j.get_ref<nlohmann::json::string_t
const&>());
304 case boolean:
return func(
j.get_ref<nlohmann::json::boolean_t
const&>());
307 case number_float:
return func(
j.get_ref<nlohmann::json::number_float_t
const&>());
308 case binary:
return func(
j.get_ref<nlohmann::json::binary_t
const&>());
310 return func(
nullptr);
314 constexpr const char* type_name(nlohmann::json::value_t type)
noexcept
318 using enum nlohmann::detail::value_t;
345 inline nlohmann::json
try_load_file(std::filesystem::path
const& from, nlohmann::json
const&
or_json = json::empty_json)
349 return ec ?
or_json : nlohmann::json::from_ubjson(source);
352 inline nlohmann::json
load_file(std::filesystem::path
const& from, std::error_code&
ec)
355 return ec ? nlohmann::json{} : nlohmann::json::from_ubjson(source);
358 inline nlohmann::json
load_file(std::filesystem::path
const& from)
366 std::throw_with_nested(std::runtime_error{ format(
"while trying to load ubjson file {}", from.string()) });
370 inline void save_file(std::filesystem::path
const&
to, nlohmann::json
const&
j)
372 std::ofstream
out{
to };
373 nlohmann::json::to_ubjson(
j, nlohmann::detail::output_adapter<char, std::string>(
out),
true,
true);
385 inline nlohmann::json
try_load_file(std::filesystem::path
const& from, nlohmann::json
const&
or_json = json::empty_json)
389 return ec ?
or_json : nlohmann::json::from_cbor(source);
393 inline void save_file(std::filesystem::path
const&
to, nlohmann::json
const&
j)
395 std::ofstream
out{
to };
396 nlohmann::json::to_cbor(
j, nlohmann::detail::output_adapter<char, std::string>(
out));
constexpr auto bit_count
Equal to the number of bits in the type.
nlohmann::json try_load_file(std::filesystem::path const &from, nlohmann::json const &or_json=json::empty_json)
Tries loading a CBOR file.
void save_file(std::filesystem::path const &to, nlohmann::json const &j)
Saves a CBOR file.
nlohmann::json::value_t jtype
Smaller name for nlohmann::json::value_t.
bool field_opt(T &val, nlohmann::json const &g, std::string_view key)
Same as field() but returns if it succeeded, instead of throwing.
void field(T &val, nlohmann::json const &g, std::string_view key)
Sets the value of val to the item in json object g with key key
nlohmann::json const & get_array(nlohmann::json const &g, std::string_view key)
Gets the array value in the json object g with the key key, or an empty array if none found.
nlohmann::json const & get(nlohmann::json const &g, std::string_view key, jtype type=jtype::discarded)
Gets the item in the json object g with the key key, or an empty json object if none found.
auto visit(nlohmann::json const &j, VISIT_FUNC &&func)
Calls func with the actual value inside j; similar to std::visit
constexpr CONTAINER to(RANGE &&range, TYPES &&... args)
to<container>();
constexpr void split(std::string_view source, char delim, FUNC &&func) noexcept(noexcept(func(std::string_view{}, true)))
Performs a basic "split" operation, calling func for each part of source delimited by delim.
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.