Files
email-tracker/external/duckdb/extension/json/include/json_serializer.hpp
2025-10-24 19:21:19 -05:00

98 lines
3.4 KiB
C++

#pragma once
#include "json_common.hpp"
#include "duckdb/common/serializer/serializer.hpp"
namespace duckdb {
struct JsonSerializer : Serializer {
private:
yyjson_mut_doc *doc;
yyjson_mut_val *current_tag;
vector<yyjson_mut_val *> stack;
// Skip writing property if null
bool skip_if_null = false;
// Skip writing property if empty string, empty list or empty map.
bool skip_if_empty = false;
// Get the current json value
inline yyjson_mut_val *Current() {
return stack.back();
};
// Either adds a value to the current object with the current tag, or appends it to the current array
void PushValue(yyjson_mut_val *val);
public:
explicit JsonSerializer(yyjson_mut_doc *doc, bool skip_if_null, bool skip_if_empty, bool skip_if_default)
: doc(doc), stack({yyjson_mut_obj(doc)}), skip_if_null(skip_if_null), skip_if_empty(skip_if_empty) {
options.serialize_enum_as_string = true;
options.serialize_default_values = !skip_if_default;
}
template <class T>
static yyjson_mut_val *Serialize(T &value, yyjson_mut_doc *doc, bool skip_if_null, bool skip_if_empty,
bool skip_if_default) {
JsonSerializer serializer(doc, skip_if_null, skip_if_empty, skip_if_default);
value.Serialize(serializer);
return serializer.GetRootObject();
}
template <class T>
static string SerializeToString(T &value) {
auto doc = yyjson_mut_doc_new(nullptr);
JsonSerializer serializer(doc, false, false, false);
value.Serialize(serializer);
auto result_obj = serializer.GetRootObject();
idx_t len = 0;
auto data = yyjson_mut_val_write_opts(result_obj, JSONCommon::WRITE_PRETTY_FLAG, nullptr,
reinterpret_cast<size_t *>(&len), nullptr);
return string(data, len);
}
yyjson_mut_val *GetRootObject() {
D_ASSERT(stack.size() == 1); // or we forgot to pop somewhere
return stack.front();
};
//===--------------------------------------------------------------------===//
// Nested Types Hooks
//===--------------------------------------------------------------------===//
void OnPropertyBegin(const field_id_t field_id, const char *tag) final;
void OnPropertyEnd() final;
void OnOptionalPropertyBegin(const field_id_t field_id, const char *tag, bool present) final;
void OnOptionalPropertyEnd(bool present) final;
void OnListBegin(idx_t count) final;
void OnListEnd() final;
void OnObjectBegin() final;
void OnObjectEnd() final;
void OnNullableBegin(bool present) final;
void OnNullableEnd() final;
//===--------------------------------------------------------------------===//
// Primitive Types
//===--------------------------------------------------------------------===//
void WriteNull() final;
void WriteValue(uint8_t value) final;
void WriteValue(int8_t value) final;
void WriteValue(uint16_t value) final;
void WriteValue(int16_t value) final;
void WriteValue(uint32_t value) final;
void WriteValue(int32_t value) final;
void WriteValue(uint64_t value) final;
void WriteValue(int64_t value) final;
void WriteValue(hugeint_t value) final;
void WriteValue(uhugeint_t value) final;
void WriteValue(float value) final;
void WriteValue(double value) final;
void WriteValue(const string_t value) final;
void WriteValue(const string &value) final;
void WriteValue(const char *value) final;
void WriteValue(bool value) final;
void WriteDataPtr(const_data_ptr_t ptr, idx_t count) final;
};
} // namespace duckdb