structs
#include "json_struct.h"
#include <vector>
JS_ENUM(Error, None, InvalidRange, IllegalParam, Nullptr, OverLimitLen)
JS_ENUM_DECLARE_STRING_PARSER(Error)
// 搜索匹配区域
struct RangeContent {
size_t start;
size_t end;
std::string content;
JS_OBJ(start, end, content);
};
struct Result {
Error errorCode;
std::vector<RangeContent> contents;
JS_OBJECT(JS_MEMBER(errorCode), JS_MEMBER(contents));
};
void test() {
// 序列
Result result;
std::string json = JS::serializeStruct(result, JS::SerializerOptions(JS::SerializerOptions::Compact));
// 反序列
Result resultNew;
JS::ParseContext parseContext(json);
auto error = parseContext.parseTo(resultNew);
if (JS::Error::NoError != error) {
std::string errorStr = parseContext.makeErrorString();
fprintf(stderr, "Error parsing struct %s\n", errorStr.c_str());
}
}
jsonifier
//
// Created by ws on 2024/8/29.
//
#include <vector>
#include "jsonifier/String.hpp"
#include "jsonifier/Tuple.hpp"
#include "jsonifier/Index.hpp"
#include "jsonifier/Serializer.hpp"
#include "jsonifier/JsonifierCore.hpp"
namespace TestNS {
struct fixed_object_t {
std::vector<int32_t> int_array;
std::vector<float> float_array;
std::vector<double> double_array;
};
struct fixed_name_object_t {
jsonifier::string name0{};
jsonifier::string name1{};
jsonifier::string name2{};
jsonifier::string name3{};
jsonifier::string name4{};
};
struct nested_object_t {
std::vector<std::array<double, 3>> v3s{};
jsonifier::string id{};
};
struct another_object_t {
jsonifier::string string{};
jsonifier::string another_string{};
bool boolean{};
nested_object_t nested_object{};
};
struct obj_t {
fixed_object_t fixed_object{};
fixed_name_object_t fixed_name_object{};
another_object_t another_object{};
std::vector<jsonifier::string> string_array{};
jsonifier::string string{};
double Number{};
bool boolean{};
bool another_bool{};
};
}
namespace jsonifier {
template<> struct core<TestNS::fixed_object_t> {
using value_type = TestNS::fixed_object_t;
static constexpr auto parseValue = createValue("int_array", &value_type::int_array, "float_array", &value_type::float_array, "double_array", &value_type::double_array);
};
template<> struct core<TestNS::fixed_name_object_t> {
using value_type = TestNS::fixed_name_object_t;
static constexpr auto parseValue = createValue("name0", &value_type::name0, "name1", &value_type::name1, "name2", &value_type::name2, "name3", &value_type::name3, "name4", &value_type::name4);
};
template<> struct core<TestNS::nested_object_t> {
using value_type = TestNS::nested_object_t;
static constexpr auto parseValue = createValue("v3s", &value_type::v3s, "id", &value_type::id);
};
template<> struct core<TestNS::another_object_t> {
using value_type = TestNS::another_object_t;
static constexpr auto parseValue =
createValue("string", &value_type::string, "another_string", &value_type::another_string, "boolean", &value_type::boolean, "nested_object", &value_type::nested_object);
};
template<> struct core<TestNS::obj_t> {
using value_type = TestNS::obj_t;
static constexpr auto parseValue =
createValue("fixed_object", &value_type::fixed_object, "fixed_name_object", &value_type::fixed_name_object, "another_object", &value_type::another_object, "string_array",
&value_type::string_array, "string", &value_type::string, "Number", &value_type::Number, "boolean", &value_type::boolean, "another_bool", &value_type::another_bool);
};
}
int main() {
jsonifier::jsonifier_core myParser{};
// jsonifier::string buffer{ json_data };
TestNS::obj_t obj{};
obj.string = "hello world";
obj.Number = 12.33242;
// Serialize and obtain the serialized JSON string directly.
jsonifier::serialize_options options;
options.prettify = true; // Enable prettifying
options.indentSize = 2; // Set custom prettifyJson options if needed.
auto stringToWrite = myParser.serializeJson(obj);
std::cout << stringToWrite << std::endl;
// Deserialize
TestNS::obj_t newObj{};
std::string dataToParse = "{\"Number\":12.33242,\"another_object\":{\"another_string\":\"\",\"boolean\":false,\"nested_object\":{\"id\":\"\",\"v3s\":[]},\"string\":\"\"},\"another_bool\":false,\"boolean\":false,\"fixed_object\":{\"double_array\":[],\"float_array\":[],\"int_array\":[]},\"fixed_name_object\":{\"name0\":\"\",\"name1\":\"\",\"name2\":\"\",\"name3\":\"\",\"name4\":\"\"},\"string_array\":[],\"string\":\"hello world\"}";
auto result = myParser.parseJson<jsonifier::parse_options{ .validateJson = true, .minified = false }>(newObj, dataToParse);
std::cout << newObj.string << " " << newObj.Number << std::endl;
}
{"Number":12.33242,"another_object":{"another_string":"","boolean":false,"nested_object":{"id":"","v3s":[]},"string":""}
,"another_bool":false,"boolean":false,"fixed_object":{"double_array":[],"float_array":[],"int_array":[]},"fixed_name_obj
ect":{"name0":"","name1":"","name2":"","name3":"","name4":""},"string_array":[],"string":"hello world"}
hello world 12.3324
nlohmann
#include "nlohmann/json.hpp"
using json = nlohmann::json;
template <typename T>
bool json2obj(const char* pcJson, T &out, std::string *err = nullptr)
{
try {
out = json::parse(pcJson);
return true;
} catch (const json::exception &e) {
if (err != nullptr)
*err = e.what();
return false;
}
}
enum class Type {
MAN = 4,
WONMAN,
NONE,
};
NLOHMANN_JSON_SERIALIZE_ENUM(Type, {{Type::WONMAN, "WONMAN"},
{Type::MAN, "MAN"}, {Type::NONE, "NONE"}, });
struct Value{
std::optional<bool> isBeyond;//是否超出
std::optional<Type> type;//类型
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Value, isBeyond, type)
/* 自定义Key-Value映射解析
inline void to_json(nlohmann::json& j, const Value& t)
{
j["dataType"] = t.type;
j["over"] = t.isBeyond;
}
inline void from_json(const nlohmann::json& j, Value& t)
{
t.type = j["dataType"];
t.isBeyond = j["over"];
}*/
// json解析
int main() {
Value value;
nlohmann::json json_data = value;
value = json_data;
// Value value = nlohmann::json::parse(event->argument());
// nlohmann::json json_data = nlohmann::json::parse(json_string);
// nlohmann::json json_data = json_string;
// std::string json_string = json_data.dump();
}
draw_json_link
#include <daw/daw_span.h>
#include <daw/daw_tuple_forward.h>
#include <daw/json/daw_json_link.h>
#include <daw/json/daw_json_schema.h>
#include <cassert>
#include <cstdio>
#include <iostream>
#include <map>
#include <string>
#include <tuple>
#include <variant>
struct Bar {
int a = 9;
int type = 0;
};
struct Umm {
double a = 12.1;
int type = 1;
};
struct Foo {
int a = 1;
double b = 2.2;
std::string c = "3";
std::vector<int> d = { 1, 2, 3, 4 };
Bar e;
std::map<std::string, Bar> f;
std::map<int, float> g;
std::variant<int, std::string, bool> h;
std::variant<int, std::string, bool, Bar, Umm> i;
std::optional<int> j;
std::unique_ptr<int[]> l = std::unique_ptr<int[]>( new int[0] );
int k;
std::tuple<int, double> m{ 99, 98.8 };
std::variant<Bar, Umm> n{ Umm{} };
std::tuple<double, std::string, int, std::variant<Bar, Umm>> o{ 1.1, "2", 1,
Umm{} };
};
struct FooBoo {
int a = 1;
double b = 2.2;
std::string_view c = "3";
Bar e{ };
std::variant<int, std::string_view, bool> h{ 5 };
std::variant<int, std::string_view, bool, Bar, Umm> i{ bool{} };
std::optional<int> j{ };
int k{ };
std::tuple<int, double> m{ 99, 98.8 };
std::variant<Bar, Umm> n{ Umm{} };
std::tuple<double, std::string_view, int, std::variant<Bar, Umm>> o{
1.1, "2", 1, Umm{} };
};
template<typename... Ts>
struct IdentitySwitcher {
constexpr std::size_t operator( )( std::size_t n ) const {
assert( n < sizeof...( Ts ) );
return n;
}
inline std::size_t operator( )( Foo const &f ) const {
return f.i.index( );
}
inline std::size_t operator( )( FooBoo const &f ) const {
return f.i.index( );
}
};
template<typename T>
struct UniquePtrArrayCtor {
constexpr std::unique_ptr<T[]> operator( )( ) const {
return { };
}
template<typename Iterator>
inline std::unique_ptr<T[]> operator( )( Iterator first, Iterator last,
std::size_t sz ) const {
auto result = std::unique_ptr<T[]>( new T[static_cast<std::size_t>( sz )] );
auto out_last = std::copy( first, last, result.get( ) );
(void)out_last;
auto const elements_copied = out_last - result.get( );
(void)elements_copied;
assert( elements_copied >= 0 );
assert( static_cast<std::size_t>( elements_copied ) == sz );
return result;
}
};
namespace daw::json {
inline constexpr char const mem_a[] = "a";
inline constexpr char const mem_b[] = "b";
inline constexpr char const mem_c[] = "c";
inline constexpr char const mem_d[] = "d";
inline constexpr char const mem_e[] = "e";
inline constexpr char const mem_f[] = "f";
inline constexpr char const mem_g[] = "g";
inline constexpr char const gkey[] = "k";
inline constexpr char const gvalue[] = "v";
inline constexpr char const mem_h[] = "h";
inline constexpr char const mem_type[] = "type";
inline constexpr char const mem_i[] = "i";
inline constexpr char const mem_j[] = "j";
inline constexpr char const mem_k[] = "k";
inline constexpr char const mem_l[] = "l";
inline constexpr char const mem_m[] = "m";
inline constexpr char const mem_n[] = "n";
inline constexpr char const mem_o[] = "o";
template<>
struct json_data_contract<Bar> {
using type = json_tuple_member_list<int, int>;
static constexpr auto to_json_data( Bar const &b ) {
return std::forward_as_tuple( b.a, b.type );
}
};
template<>
struct json_data_contract<Umm> {
using type = json_tuple_member_list<double, int>;
static constexpr auto to_json_data( Umm const &b ) {
return std::forward_as_tuple( b.a, b.type );
}
};
template<>
struct json_data_contract<Foo> {
using force_aggregate_construction = void;
using type = json_member_list<
json_link<mem_a, int>, json_link<mem_b, double>,
json_link<mem_c, std::string>, json_link<mem_d, std::vector<int>>,
json_link<mem_e, Bar>, json_link<mem_f, std::map<std::string, Bar>>,
json_key_value_array<mem_g, std::map<int, float>,
json_link<gvalue, float>, json_link<gkey, int>>,
json_variant<mem_h, std::variant<int, std::string, bool>>,
json_tagged_variant<mem_i, std::variant<int, std::string, bool, Bar, Umm>,
json_link<mem_type, std::size_t>,
IdentitySwitcher<int, std::string, bool, Bar, Umm>>,
json_link<mem_j, std::optional<int>>,
json_sized_array<mem_l, int, json_link<mem_k, int>,
std::unique_ptr<int[]>, UniquePtrArrayCtor<int>>,
json_link<mem_k, int>, json_tuple<mem_m, std::tuple<int, double>>,
json_intrusive_variant<mem_n, std::variant<Bar, Umm>,
json_tuple_member<1, std::size_t>,
IdentitySwitcher<Bar, Umm>>,
json_tuple<mem_o,
std::tuple<double, std::string, int, std::variant<Bar, Umm>>,
json_tuple_types_list<
double, std::string, int,
json_tagged_variant_no_name<
std::variant<Bar, Umm>, json_tuple_member<2, std::size_t>,
IdentitySwitcher<Bar, Umm>>>>>;
static inline auto to_json_data( Foo const &v ) {
return daw::forward_nonrvalue_as_tuple(
v.a, v.b, v.c, v.d, v.e, v.f, v.g, v.h, v.i, v.j,
daw::span( v.l.get( ), static_cast<std::size_t>( v.k ) ), v.k, v.m, v.n,
v.o );
}
};
template<>
struct json_data_contract<FooBoo> {
using force_aggregate_construction = void;
using type = json_member_list<
json_link<mem_a, int>, json_link<mem_b, double>,
json_link<mem_c, std::string_view>, json_link<mem_e, Bar>,
json_variant<mem_h, std::variant<int, std::string_view, bool>>,
json_tagged_variant<
mem_i, std::variant<int, std::string_view, bool, Bar, Umm>,
json_link<mem_type, std::size_t>,
IdentitySwitcher<int, std::string_view, bool, Bar, Umm>>,
json_link<mem_j, std::optional<int>>,
json_link<mem_k, int>, json_tuple<mem_m, std::tuple<int, double>>,
json_intrusive_variant<mem_n, std::variant<Bar, Umm>,
json_tuple_member<1, std::size_t>,
IdentitySwitcher<Bar, Umm>>,
json_tuple<
mem_o,
std::tuple<double, std::string_view, int, std::variant<Bar, Umm>>,
json_tuple_types_list<
double, std::string_view, int,
json_tagged_variant_no_name<std::variant<Bar, Umm>,
json_tuple_member<2, std::size_t>,
IdentitySwitcher<Bar, Umm>>>>>;
static inline auto to_json_data( FooBoo const &v ) {
return daw::forward_nonrvalue_as_tuple( v.a, v.b, v.c, v.e, v.h, v.i, v.j,
v.k, v.m, v.n, v.o );
}
};
} // namespace daw::json
int main( ) {
using namespace daw::json::options;
std::string result = daw::json::to_json_schema<Foo>(
"", "Foo", output_flags<SerializationFormat::Pretty> );
puts( result.c_str( ) );
puts( "----\n" );
std::string json_str1 =
daw::json::to_json( Foo{ }, output_flags<SerializationFormat::Pretty> );
puts( json_str1.c_str( ) );
puts( "\n----\n\n" );
auto foo2 = daw::json::from_json<Foo>( json_str1 );
(void)foo2;
std::string json_str2 = daw::json::to_json( FooBoo{ } );
puts( json_str2.c_str( ) );
auto fooboo = daw::json::from_json<FooBoo>( json_str2 );
std::cout << "\n----------------------------------------\n"
<< daw::json::to_json( fooboo ) << '\n';
}
参考
GitHub - RealTimeChris/Jsonifier: A few classes for parsing and serializing objects from/into JSON, in C++ - very rapidly.
GitHub - jorgen/json_struct: json_struct is a single header only C++ library for parsing JSON directly to C++ structs and vice versa
GitHub - nlohmann/json: JSON for Modern C++
GitHub - beached/daw_json_link: Fast, convenient JSON serialization and parsing in C++
GitHub - stephenberry/json_performance: Performance profiling of JSON libraries