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 <cstdint>
9#include <nlohmann/json.hpp>
10#include <optional>
11#include <string>
12#include <string_view>
13
14#include "cppfig/value.h"
15
16namespace cppfig {
17
18// Conversion utilities
19
21inline auto JsonToValue(const nlohmann::json& json) -> Value
22{
23 if (json.is_null()) {
24 return {};
25 }
26 if (json.is_boolean()) {
27 return { json.get<bool>() };
28 }
29 if (json.is_number_integer()) {
30 return { json.get<std::int64_t>() };
31 }
32 if (json.is_number_float()) {
33 return { json.get<double>() };
34 }
35 if (json.is_string()) {
36 return { json.get<std::string>() };
37 }
38 if (json.is_object()) {
39 auto obj = Value::Object();
40 for (const auto& [key, val] : json.items()) {
41 obj[key] = JsonToValue(val);
42 }
43 return obj;
44 }
45 if (json.is_array()) {
46 auto arr = Value::Array();
47 for (const auto& element : json) {
48 arr.Elements().push_back(JsonToValue(element));
49 }
50 return arr;
51 }
52 return {};
53}
54
56inline auto ValueToJson(const Value& value) -> nlohmann::json
57{
58 if (value.IsNull()) {
59 return nullptr;
60 }
61 if (value.IsBoolean()) {
62 return value.Get<bool>();
63 }
64 if (value.IsInteger()) {
65 return value.Get<std::int64_t>();
66 }
67 if (value.IsDouble()) {
68 return value.Get<double>();
69 }
70 if (value.IsString()) {
71 return value.Get<std::string>();
72 }
73 if (value.IsObject()) {
74 nlohmann::json json = nlohmann::json::object();
75 for (const auto& [key, val] : value.Items()) {
76 json[key] = ValueToJson(val);
77 }
78 return json;
79 }
80 if (value.IsArray()) {
81 nlohmann::json json = nlohmann::json::array();
82 for (const auto& element : value.Elements()) {
83 json.push_back(ValueToJson(element));
84 }
85 return json;
86 }
87 return nullptr;
88}
89
95
97 static auto Parse(std::istream& is) -> StatusOr<Value>
98 {
99 try {
100 nlohmann::json data;
101 is >> data;
102 return JsonToValue(data);
103 }
104 catch (const nlohmann::json::parse_error& e) {
105 return InvalidArgumentError(std::string("JSON parse error: ") + e.what());
106 }
107 }
108
110 static auto ParseString(std::string_view str) -> StatusOr<Value>
111 {
112 try {
113 return JsonToValue(nlohmann::json::parse(str));
114 }
115 catch (const nlohmann::json::parse_error& e) {
116 return InvalidArgumentError(std::string("JSON parse error: ") + e.what());
117 }
118 }
119
121 static auto Stringify(const Value& data, int indent = 4) -> std::string { return ValueToJson(data).dump(indent); }
122};
123
124// ADL-based ConfigTraits helper
125
127template <typename T>
128concept HasJsonAdl = requires(const T& value, nlohmann::json& json) {
129 { to_json(json, value) };
130 { from_json(json, std::declval<T&>()) };
131};
132
142template <typename T>
143 requires HasJsonAdl<T>
145 static auto Serialize(const T& value) -> Value
146 {
147 nlohmann::json json;
148 to_json(json, value);
149 return JsonToValue(json);
150 }
151
152 static auto Deserialize(const Value& value) -> std::optional<T>
153 {
154 try {
155 nlohmann::json json = ValueToJson(value);
156 T result;
157 from_json(json, result);
158 return result;
159 }
160 catch (...) {
161 return std::nullopt;
162 }
163 }
164
165 static auto ToString(const T& value) -> std::string { return Serialize(value).Dump(); }
166
167 static auto FromString(std::string_view str) -> std::optional<T>
168 {
169 try {
170 auto json = nlohmann::json::parse(str);
171 return Deserialize(JsonToValue(json));
172 }
173 catch (...) {
174 return std::nullopt;
175 }
176 }
177};
178
179} // namespace cppfig
A value-or-error type, similar to std::expected (C++23).
Definition status.h:102
A self-contained, recursive value type for configuration data.
Definition value.h:32
static auto Array() -> Value
Creates an empty array value.
Definition value.h:147
static auto Object() -> Value
Creates an empty object value.
Definition value.h:139
Concept for types that have nlohmann::json ADL serialization.
Definition json.h:128
C++20 compile-time type-safe configuration library.
Definition conf.h:17
auto ValueToJson(const Value &value) -> nlohmann::json
Converts a cppfig::Value to a nlohmann::json value.
Definition json.h:56
auto JsonToValue(const nlohmann::json &json) -> Value
Converts a nlohmann::json value to a cppfig::Value.
Definition json.h:21
auto InvalidArgumentError(std::string message) -> Status
Returns an InvalidArgument error status.
Definition status.h:63
Helper to create ConfigTraits for types with nlohmann::json ADL.
Definition json.h:144
static auto Serialize(const T &value) -> Value
Definition json.h:145
static auto ToString(const T &value) -> std::string
Definition json.h:165
static auto FromString(std::string_view str) -> std::optional< T >
Definition json.h:167
static auto Deserialize(const Value &value) -> std::optional< T >
Definition json.h:152
JSON serializer using nlohmann::json.
Definition json.h:93
static auto Stringify(const Value &data, int indent=4) -> std::string
Converts a Value tree to a formatted JSON string.
Definition json.h:121
static auto Parse(std::istream &is) -> StatusOr< Value >
Parses JSON from an input stream.
Definition json.h:97
static auto ParseString(std::string_view str) -> StatusOr< Value >
Parses JSON from a string.
Definition json.h:110