Features
- JSONC parse mode
- Copiable
Json objects
- Default construction (representing
null) is "free"
as_string_view()
- Heterogenous arrays
- Escaped text
- Implicit construction for nulls, booleans, numbers, strings
- Serialization, pretty-print (default)
- Customization points for
from_json and to_json
- Build tree from scratch
Limitations
- Escaped unicode (eg
\u1F604) not currently supported
Usage
JSONC
dj::ParseMode controls whether JSONC features are accepted or rejected during parsing:
- Single-line comments:
//
- Multi-line comments:
/* ... */
- Trailing commans:
[1,2,]
There are three parse modes available:
dj::ParseMode::Auto looks for a mode line at the start of the string, per the spec:
Or
If found, the mode is set to Jsonc, else Strict.
dj::Json::parse() and dj::Json::from_file() accept a dj::ParseMode parameter, defaulted to dj::ParseMode::Auto.
Input
dj::Json is the primary type around which the entire library's interface is designed. Use the static member function dj::Json::parse() to attempt to parse text into a Json value. It returns a dj::Result (ie, std::expected<Json, Error>):
constexpr auto text = R"({
"elements": [-2.5e3, "bar"],
"foo": "party",
"universe": 42
})";
auto& json = result.value();
assert(!json.is_null());
static auto parse(std::string_view text, ParseMode mode=ParseMode::Auto) -> Result
Parse JSON text.
Access values of Objects via dj::Json::operator[](std::string_view). A const Json will return null for non-existent keys, whereas a mutable Json will return a reference to a newly created value:
auto const& elements = json["elements"];
auto const& foo = json["foo"];
auto const& universe = json["universe"];
assert(std::as_const(json)["nonexistent"].is_null());
Access values of Arrays via dj::Json::operator[](std::size_t). A const Json will return null for out-of-bound indices, whereas a mutable Json will resize itself and return a reference to a newly created value:
auto const& elem0 = elements[0];
auto const& elem1 = elements[1];
assert(elements[2].is_null());
Check the type of a Json value via dj::Json::get_type() / dj::Json::is_*():
assert(elem1.is_string());
assert(foo.is_string());
assert(universe.is_number());
Convert to a C++ type via dj::Json::as*():
assert(elem0.as_double() == -2500.0);
assert(elem1.as_string_view() == "bar");
assert(foo.as_string_view() == "party");
assert(universe.as<int>() == 42);
Iterate over Arrays via dj::Json::as_array(). Array elements are ordered:
for (auto const [index, value] :
std::views::enumerate(elements.as_array())) {
std::println("[{}]: {}", index, value);
}
Iterate over Objects via dj::Json::as_object(). Object elements are not ordered:
for (auto const& [key, value] : json.as_object()) {
std::println(R"("{}": {})", key, value);
}
Output
Use dj::Json::set*() to overwrite the value of a Json with a literal (null / boolean / number / string), an empty Array / Object, or another Json value. It can also be constructed this way:
assert(json.is_null());
json.set_number(42);
assert(json.as<int>() == 42);
json.set_object();
assert(json.is_object());
assert(json.as_object().empty());
assert(json.is_array());
assert(json.as_array().empty());
assert(json.as_bool());
Library interface, represents a valid JSON value.
Definition json.hpp:77
static auto empty_array() -> Json const &
Obtain a Json representing an empty Array value.
Serialization
Serialize to strings via dj::Json::serialize() or dj::to_string() or std::format() (and related). The first two can be customized via dj::SerializeOptions. std::formatter<Json> uses SerializeFlag::NoSpaces for compact output.
.newline = "\n",
};
auto const serialized = json.serialize(options);
std::print("{}", serialized);
@ TrailingNewline
Append newline at the end. Ignored if NoSpaces is set.
Definition json.hpp:43
@ SortKeys
Sort keys lexicographically.
Definition json.hpp:41
Serialization options.
Definition json.hpp:53
std::string_view indent
Indentation string. Ignored if SerializeFlag::NoSpaces is set.
Definition json.hpp:55
Read from / write to files via dj::Json::from_file() / dj::Json::to_file().
Customization
Parse your own types:
namespace foo {
struct Item {
std::string name{};
int weight{};
auto operator==(Item const&) const -> bool = default;
};
}
to_json(out[
"weight"], item.weight);
}
}
auto const src = foo::Item{
.name = "Orb",
.weight = 5,
};
auto dst = foo::Item{};
assert(src == dst);
void from_json(Json const &json, Type &value, Type const fallback={})
Assign JSON as value.
Definition json.hpp:260
void to_json(Json &json, Type const &value)
Assign value to JSON.
Definition json.hpp:266