50#if __has_include( <nfx/containers/PerfectHashMap.h>)
52# include <nfx/containers/PerfectHashMap.h>
54namespace nfx::serialization::json
59 template <
typename TKey,
typename TValue,
typename HashType, HashType Seed,
typename Hasher,
typename KeyEqual>
60 struct SerializationTraits<nfx::containers::PerfectHashMap<TKey, TValue, HashType, Seed, Hasher, KeyEqual>>
68 static void serialize(
const nfx::containers::PerfectHashMap<TKey, TValue, HashType, Seed, Hasher, KeyEqual>& obj, Document& doc )
71 doc.set<Document::Array>(
"" );
72 auto arrayRef = doc.get<Document::Array>(
"" );
74 if ( !arrayRef.has_value() )
80 for (
auto it = obj.begin(); it != obj.end(); ++it )
82 const auto& pair = *it;
83 const TKey& key = pair.first;
84 const TValue& value = pair.second;
88 pairDoc.set<Document::Object>(
"" );
92 Serializer<TKey> keySerializer;
93 keyDoc = keySerializer.serialize( key );
97 Serializer<TValue> valueSerializer;
98 valueDoc = valueSerializer.serialize( value );
101 if ( keyDoc.is<std::string>(
"" ) )
103 auto str = keyDoc.get<std::string>(
"" );
104 pairDoc.set<std::string>(
"/key", str.value() );
106 else if ( keyDoc.is<
int>(
"" ) )
108 auto val = keyDoc.get<int64_t>(
"" );
109 pairDoc.set<int64_t>(
"/key", val.value() );
111 else if ( keyDoc.is<
double>(
"" ) )
113 auto val = keyDoc.get<
double>(
"" );
114 pairDoc.set<
double>(
"/key", val.value() );
116 else if ( keyDoc.is<
bool>(
"" ) )
118 auto val = keyDoc.get<
bool>(
"" );
119 pairDoc.set<
bool>(
"/key", val.value() );
121 else if ( keyDoc.is<Document::Array>(
"" ) || keyDoc.is<Document::Object>(
"" ) )
123 pairDoc.set<Document>(
"/key", keyDoc );
126 if ( valueDoc.is<std::string>(
"" ) )
128 auto str = valueDoc.get<std::string>(
"" );
129 pairDoc.set<std::string>(
"/value", str.value() );
131 else if ( valueDoc.is<
int>(
"" ) )
133 auto val = valueDoc.get<int64_t>(
"" );
134 pairDoc.set<int64_t>(
"/value", val.value() );
136 else if ( valueDoc.is<
double>(
"" ) )
138 auto val = valueDoc.get<
double>(
"" );
139 pairDoc.set<
double>(
"/value", val.value() );
141 else if ( valueDoc.is<
bool>(
"" ) )
143 auto val = valueDoc.get<
bool>(
"" );
144 pairDoc.set<
bool>(
"/value", val.value() );
146 else if ( valueDoc.isNull(
"" ) )
148 pairDoc.setNull(
"/value" );
150 else if ( valueDoc.is<Document::Array>(
"" ) || valueDoc.is<Document::Object>(
"" ) )
152 pairDoc.set<Document>(
"/value", valueDoc );
156 arrayRef->append<Document>( pairDoc );
166 static void deserialize( nfx::containers::PerfectHashMap<TKey, TValue, HashType, Seed, Hasher, KeyEqual>& obj,
const Document& doc )
168 if ( !doc.is<Document::Array>(
"" ) )
170 throw std::runtime_error(
"Cannot deserialize non-array JSON value into PerfectHashMap" );
174 std::vector<std::pair<TKey, TValue>> items;
177 auto arrayOpt = doc.get<Document::Array>(
"" );
178 if ( arrayOpt.has_value() )
180 for (
const auto& pairDoc : arrayOpt.value() )
184 if ( pairDoc.contains(
"/key" ) )
186 Document keyDoc = pairDoc.get<Document>(
"/key" ).value_or( Document{} );
187 Serializer<TKey> keySerializer;
188 key = keySerializer.deserialize( keyDoc );
193 if ( pairDoc.contains(
"/value" ) )
195 Document valueDoc = pairDoc.get<Document>(
"/value" ).value_or( Document{} );
196 Serializer<TValue> valueSerializer;
197 value = valueSerializer.deserialize( valueDoc );
200 items.emplace_back( std::move( key ), std::move( value ) );
204 obj = nfx::containers::PerfectHashMap<TKey, TValue, HashType, Seed, Hasher, KeyEqual>( std::move( items ) );
215#if __has_include( <nfx/containers/FastHashMap.h>)
217# include <nfx/containers/FastHashMap.h>
219namespace nfx::serialization::json
224 template <
typename TKey,
typename TValue,
typename HashType, HashType Seed,
typename Hasher,
typename KeyEqual>
225 struct SerializationTraits<nfx::containers::FastHashMap<TKey, TValue, HashType, Seed, Hasher, KeyEqual>>
233 static void serialize(
const nfx::containers::FastHashMap<TKey, TValue, HashType, Seed, Hasher, KeyEqual>& obj, Document& doc )
236 doc.set<Document::Array>(
"" );
237 auto arrayRef = doc.get<Document::Array>(
"" );
239 if ( !arrayRef.has_value() )
245 for (
auto it = obj.begin(); it != obj.end(); ++it )
247 const auto& pair = *it;
248 const TKey& key = pair.first;
249 const TValue& value = pair.second;
253 pairDoc.set<Document::Object>(
"" );
257 Serializer<TKey> keySerializer;
258 keyDoc = keySerializer.serialize( key );
262 Serializer<TValue> valueSerializer;
263 valueDoc = valueSerializer.serialize( value );
266 if ( keyDoc.is<std::string>(
"" ) )
268 auto str = keyDoc.get<std::string>(
"" );
269 pairDoc.set<std::string>(
"/key", str.value() );
271 else if ( keyDoc.is<
int>(
"" ) )
273 auto val = keyDoc.get<int64_t>(
"" );
274 pairDoc.set<int64_t>(
"/key", val.value() );
276 else if ( keyDoc.is<
double>(
"" ) )
278 auto val = keyDoc.get<
double>(
"" );
279 pairDoc.set<
double>(
"/key", val.value() );
281 else if ( keyDoc.is<
bool>(
"" ) )
283 auto val = keyDoc.get<
bool>(
"" );
284 pairDoc.set<
bool>(
"/key", val.value() );
286 else if ( keyDoc.is<Document::Array>(
"" ) || keyDoc.is<Document::Object>(
"" ) )
288 pairDoc.set<Document>(
"/key", keyDoc );
292 if ( valueDoc.is<std::string>(
"" ) )
294 auto str = valueDoc.get<std::string>(
"" );
295 pairDoc.set<std::string>(
"/value", str.value() );
297 else if ( valueDoc.is<
int>(
"" ) )
299 auto val = valueDoc.get<int64_t>(
"" );
300 pairDoc.set<int64_t>(
"/value", val.value() );
302 else if ( valueDoc.is<
double>(
"" ) )
304 auto val = valueDoc.get<
double>(
"" );
305 pairDoc.set<
double>(
"/value", val.value() );
307 else if ( valueDoc.is<
bool>(
"" ) )
309 auto val = valueDoc.get<
bool>(
"" );
310 pairDoc.set<
bool>(
"/value", val.value() );
312 else if ( valueDoc.isNull(
"" ) )
314 pairDoc.setNull(
"/value" );
316 else if ( valueDoc.is<Document::Array>(
"" ) || valueDoc.is<Document::Object>(
"" ) )
318 pairDoc.set<Document>(
"/value", valueDoc );
322 arrayRef->append<Document>( pairDoc );
332 static void deserialize( nfx::containers::FastHashMap<TKey, TValue, HashType, Seed, Hasher, KeyEqual>& obj,
const Document& doc )
338 if ( doc.is<Document::Object>(
"" ) )
341 auto objectOpt = doc.get<Document::Object>(
"" );
342 if ( objectOpt.has_value() )
344 for (
const auto& [keyStr, valueDoc] : objectOpt.value() )
348 if constexpr ( std::is_same_v<TKey, std::string> )
355 keyDoc.set(
"", keyStr );
356 Serializer<TKey> keySerializer;
357 key = keySerializer.deserialize( keyDoc );
362 Serializer<TValue> valueSerializer;
363 value = valueSerializer.deserialize( valueDoc );
364 obj.insertOrAssign( std::move( key ), std::move( value ) );
369 else if ( doc.is<Document::Array>(
"" ) )
372 auto arrayOpt = doc.get<Document::Array>(
"" );
373 if ( arrayOpt.has_value() )
375 for (
const auto& pairDoc : arrayOpt.value() )
379 if ( pairDoc.contains(
"/key" ) )
381 Document keyDoc = pairDoc.get<Document>(
"/key" ).value_or( Document{} );
382 Serializer<TKey> keySerializer;
383 key = keySerializer.deserialize( keyDoc );
388 if ( pairDoc.contains(
"/value" ) )
390 Document valueDoc = pairDoc.get<Document>(
"/value" ).value_or( Document{} );
391 Serializer<TValue> valueSerializer;
392 value = valueSerializer.deserialize( valueDoc );
395 obj.insertOrAssign( std::move( key ), std::move( value ) );
401 throw std::runtime_error(
"Cannot deserialize JSON value into FastHashMap: must be object or array" );
413#if __has_include( <nfx/containers/FastHashSet.h>)
415# include <nfx/containers/FastHashSet.h>
417namespace nfx::serialization::json
422 template <
typename TKey,
typename HashType, HashType Seed,
typename Hasher,
typename KeyEqual>
423 struct SerializationTraits<nfx::containers::FastHashSet<TKey, HashType, Seed, Hasher, KeyEqual>>
430 static void serialize(
const nfx::containers::FastHashSet<TKey, HashType, Seed, Hasher, KeyEqual>& obj, Document& doc )
433 doc.set<Document::Array>(
"" );
434 auto arrayRef = doc.get<Document::Array>(
"" );
436 if ( arrayRef.has_value() )
439 for (
auto it = obj.begin(); it != obj.end(); ++it )
441 const TKey& key = *it;
445 Serializer<TKey> keySerializer;
446 keyDoc = keySerializer.serialize( key );
449 if ( keyDoc.is<std::string>(
"" ) )
451 auto str = keyDoc.get<std::string>(
"" );
452 arrayRef->append<std::string>( str.value() );
454 else if ( keyDoc.is<
int>(
"" ) )
456 auto val = keyDoc.get<int64_t>(
"" );
457 arrayRef->append<int64_t>( val.value() );
459 else if ( keyDoc.is<
double>(
"" ) )
461 auto val = keyDoc.get<
double>(
"" );
462 arrayRef->append<
double>( val.value() );
464 else if ( keyDoc.is<
bool>(
"" ) )
466 auto val = keyDoc.get<
bool>(
"" );
467 arrayRef->append<
bool>( val.value() );
469 else if ( keyDoc.is<Document::Object>(
"" ) || keyDoc.is<Document::Array>(
"" ) )
472 arrayRef->append<Document>( keyDoc );
483 static void deserialize( nfx::containers::FastHashSet<TKey, HashType, Seed, Hasher, KeyEqual>& obj,
const Document& doc )
485 if ( !doc.is<Document::Array>(
"" ) )
487 throw std::runtime_error(
"Cannot deserialize non-array JSON value into FastHashSet" );
494 auto arrayOpt = doc.get<Document::Array>(
"" );
495 if ( arrayOpt.has_value() )
497 for (
const auto& elementDoc : arrayOpt.value() )
501 Serializer<TKey> keySerializer;
502 key = keySerializer.deserialize( elementDoc );
504 obj.insert( std::move( key ) );
Generic document abstraction for JSON serialization.
Serialization traits and type specializations for JSON serialization.
Templated JSON serializer with compile-time type mapping.
Default serialization traits - users can specialize this.
static void serialize(const T &obj, Document &doc)
Default serialize implementation - delegates to member method.
static void deserialize(T &obj, const Document &doc)
Default deserialize implementation - delegates to member method.