cppfig 0.1.0
Modern C++20 compile-time type-safe configuration library
Loading...
Searching...
No Matches
json.h
Go to the documentation of this file.
1#pragma once
2
3#if !defined(CPPFIG_HAS_JSON)
4// NOLINTNEXTLINE(readability-identifier-naming)
5#error "cppfig: JSON support is not enabled. Set CPPFIG_ENABLE_JSON=ON in CMake or add the 'json' vcpkg feature."
6#endif
7
8#include <nlohmann/json.hpp>
9#include <optional>
10#include <string>
11#include <string_view>
12
13#include "cppfig/value.h"
14
15namespace cppfig {
16
17// Conversion utilities
18
20inline auto JsonToValue(const nlohmann::json& json) -> Value
21{
22 if (json.is_null()) {
23 return {};
24 }
25 if (json.is_boolean()) {
26 return { json.get<bool>() };
27 }
28 if (json.is_number_integer()) {
29 return { json.get<std::int64_t>() };
30 }
31 if (json.is_number_float()) {
32 return { json.get<double>() };
33 }
34 if (json.is_string()) {
35 return { json.get<std::string>() };
36 }
37 if (json.is_object()) {
38 auto obj = Value::Object();
39 for (const auto& [key, val] : json.items()) {
40 obj[key] = JsonToValue(val);
41 }
42 return obj;
43 }
44 if (json.is_array()) {
45 auto arr = Value::Array();
46 // Array elements are not used in config settings but supported
47 // for completeness.
48 return arr;
49 }
50 return {};
51}
52
54inline auto ValueToJson(const Value& value) -> nlohmann::json
55{
56 if (value.IsNull()) {
57 return nullptr;
58 }
59 if (value.IsBoolean()) {
60 return value.Get<bool>();
61 }
62 if (value.IsInteger()) {
63 return value.Get<std::int64_t>();
64 }
65 if (value.IsDouble()) {
66 return value.Get<double>();
67 }
68 if (value.IsString()) {
69 return value.Get<std::string>();
70 }
71 if (value.IsObject()) {
72 nlohmann::json json = nlohmann::json::object();
73 for (const auto& [key, val] : value.Items()) {
74 json[key] = ValueToJson(val);
75 }
76 return json;
77 }
78 if (value.IsArray()) {
79 return nlohmann::json::array();
80 }
81 return nullptr;
82}
83
89
91 static auto Parse(std::istream& is) -> StatusOr<Value>
92 {
93 try {
94 nlohmann::json data;
95 is >> data;
96 return JsonToValue(data);
97 }
98 catch (const nlohmann::json::parse_error& e) {
99 return InvalidArgumentError(std::string("JSON parse error: ") + e.what());
100 }
101 }
102
104 static auto ParseString(std::string_view str) -> StatusOr<Value>
105 {
106 try {
107 return JsonToValue(nlohmann::json::parse(str));
108 }
109 catch (const nlohmann::json::parse_error& e) {
110 return InvalidArgumentError(std::string("JSON parse error: ") + e.what());
111 }
112 }
113
115 static auto Stringify(const Value& data, int indent = 4) -> std::string { return ValueToJson(data).dump(indent); }
116};
117
118// ADL-based ConfigTraits helper
119
121template <typename T>
122concept HasJsonAdl = requires(const T& value, nlohmann::json& json) {
123 { to_json(json, value) };
124 { from_json(json, std::declval<T&>()) };
125};
126
136template <typename T>
137 requires HasJsonAdl<T>
139 static auto Serialize(const T& value) -> Value
140 {
141 nlohmann::json json;
142 to_json(json, value);
143 return JsonToValue(json);
144 }
145
146 static auto Deserialize(const Value& value) -> std::optional<T>
147 {
148 try {
149 nlohmann::json json = ValueToJson(value);
150 T result;
151 from_json(json, result);
152 return result;
153 }
154 catch (...) {
155 return std::nullopt;
156 }
157 }
158
159 static auto ToString(const T& value) -> std::string { return Serialize(value).Dump(); }
160
161 static auto FromString(std::string_view str) -> std::optional<T>
162 {
163 try {
164 auto json = nlohmann::json::parse(str);
165 return Deserialize(JsonToValue(json));
166 }
167 catch (...) {
168 return std::nullopt;
169 }
170 }
171};
172
173} // namespace cppfig
A value-or-error type, similar to std::expected (C++23).
Definition status.h:100
A self-contained, recursive value type for configuration data.
Definition value.h:26
static auto Array() -> Value
Creates an empty array value.
Definition value.h:141
static auto Object() -> Value
Creates an empty object value.
Definition value.h:133
Concept for types that have nlohmann::json ADL serialization.
Definition json.h:122
C++20 compile-time type-safe configuration library.
Definition conf.h:13
auto ValueToJson(const Value &value) -> nlohmann::json
Converts a cppfig::Value to a nlohmann::json value.
Definition json.h:54
auto JsonToValue(const nlohmann::json &json) -> Value
Converts a nlohmann::json value to a cppfig::Value.
Definition json.h:20
auto InvalidArgumentError(std::string message) -> Status
Returns an InvalidArgument error status.
Definition status.h:61
Helper to create ConfigTraits for types with nlohmann::json ADL.
Definition json.h:138
static auto Serialize(const T &value) -> Value
Definition json.h:139
static auto ToString(const T &value) -> std::string
Definition json.h:159
static auto FromString(std::string_view str) -> std::optional< T >
Definition json.h:161
static auto Deserialize(const Value &value) -> std::optional< T >
Definition json.h:146
JSON serializer using nlohmann::json.
Definition json.h:87
static auto Stringify(const Value &data, int indent=4) -> std::string
Converts a Value tree to a formatted JSON string.
Definition json.h:115
static auto Parse(std::istream &is) -> StatusOr< Value >
Parses JSON from an input stream.
Definition json.h:91
static auto ParseString(std::string_view str) -> StatusOr< Value >
Parses JSON from a string.
Definition json.h:104