@@ -68,12 +68,14 @@ namespace cppjson
6868 explicit ObjectProxy (JsonObject& object) : _object(std::ref(object)) {}
6969
7070 template <typename T>
71+ requires (!std::same_as<std::remove_cvref_t <T>, JsonObject>)
7172 explicit (false ) operator T&()
7273 {
7374 return this ->_object .get ().As <T>();
7475 }
7576
7677 template <typename T>
78+ requires (!std::same_as<std::remove_cvref_t <T>, JsonObject>)
7779 explicit (false ) operator const T&() const
7880 {
7981 return this ->_object .get ().As <T>();
@@ -90,6 +92,8 @@ namespace cppjson
9092 {
9193 return static_cast <std::string&>(*this ) = std::string{ str };
9294 }
95+
96+ ObjectProxy operator [](const std::string& key);
9397 private:
9498 std::reference_wrapper<JsonObject> _object;
9599
@@ -106,6 +110,8 @@ namespace cppjson
106110 {
107111 return this ->_object .get ().As <T>();
108112 }
113+
114+ ConstObjectProxy operator [](const std::string& key) const ;
109115 private:
110116 std::reference_wrapper<const JsonObject> _object;
111117
@@ -127,10 +133,12 @@ namespace cppjson
127133 private:
128134 std::unordered_map<std::string, JsonObject> _nodes{};
129135
136+ friend struct std ::formatter<cppjson::JsonObject>;
130137 friend struct std ::formatter<cppjson::Object>;
131138 };
132139} // namespace cppjson
133140
141+
134142template <>
135143struct std ::formatter<cppjson::JsonObject>
136144{
@@ -144,54 +152,73 @@ struct std::formatter<cppjson::JsonObject>
144152 case cppjson::JsonType::Bool: return std::format_to (context.out (), " {}" , object.DangerousAs <bool >());
145153 case cppjson::JsonType::Number: return std::format_to (context.out (), " {}" , object.DangerousAs <double >());
146154 case cppjson::JsonType::String: return std::format_to (context.out (), " \" {}\" " , object.DangerousAs <std::string>());
155+ case cppjson::JsonType::Object:
156+ {
157+ const auto & node = object.DangerousAs <cppjson::Object>();
158+
159+ std::string built = " { " ;
160+ for (const auto & [key, value] : node._nodes )
161+ built += std::format (" \" {}\" : {}, " , key, value);
162+
163+ if (!node._nodes .empty ()) // remove trailing commas
164+ {
165+ built.pop_back ();
166+ built.pop_back ();
167+ built += " }" ;
168+ }
169+ else built += " }" ;
170+
171+ return std::format_to (context.out (), " {}" , built);
172+ }
147173 }
148174
149175 throw std::logic_error (" Unknown type" );
150176 }
151177};
152178
153179template <>
154- struct std ::formatter<cppjson::Object::ObjectProxy >
180+ struct std ::formatter<cppjson::Object>
155181{
156182 constexpr auto parse (std::format_parse_context& context) { return context.begin (); }
157183
158- auto format (const cppjson::Object::ObjectProxy & object, std::format_context& context) const
184+ auto format (const cppjson::Object& object, std::format_context& context) const
159185 {
160- return std::format_to (context.out (), " {}" , object._object .get ());
186+ std::string built = " { " ;
187+ for (const auto & [key, value] : object._nodes )
188+ built += std::format (" \" {}\" : {}, " , key, value);
189+
190+ if (!object._nodes .empty ()) // remove trailing commas
191+ {
192+ built.pop_back ();
193+ built.pop_back ();
194+ built += " }" ;
195+ }
196+ else built += " }" ;
197+
198+ return std::format_to (context.out (), " {}" , built);
161199 }
162200};
163201
164202
165203template <>
166- struct std ::formatter<cppjson::Object::ConstObjectProxy >
204+ struct std ::formatter<cppjson::Object::ObjectProxy >
167205{
168206 constexpr auto parse (std::format_parse_context& context) { return context.begin (); }
169207
170- auto format (const cppjson::Object::ConstObjectProxy & object, std::format_context& context) const
208+ auto format (const cppjson::Object::ObjectProxy & object, std::format_context& context) const
171209 {
172210 return std::format_to (context.out (), " {}" , object._object .get ());
173211 }
174212};
175213
214+
176215template <>
177- struct std ::formatter<cppjson::Object>
216+ struct std ::formatter<cppjson::Object::ConstObjectProxy >
178217{
179218 constexpr auto parse (std::format_parse_context& context) { return context.begin (); }
180219
181- auto format (const cppjson::Object& object, std::format_context& context) const
220+ auto format (const cppjson::Object::ConstObjectProxy & object, std::format_context& context) const
182221 {
183- std::string built = " { " ;
184- for (const auto & [key, value] : object._nodes )
185- built += std::format (" \" {}\" : {}, " , key, value);
186-
187- if (!object._nodes .empty ()) // remove trailing commas
188- {
189- built.pop_back ();
190- built.pop_back ();
191- built += " }" ;
192- }
193- else built += " }" ;
194-
195- return std::format_to (context.out (), " {}" , built);
222+ return std::format_to (context.out (), " {}" , object._object .get ());
196223 }
197224};
0 commit comments