Skip to content

Commit 7557069

Browse files
committed
json_writer_boost and json_writer_nlohmann
1 parent b72d2f1 commit 7557069

12 files changed

+607
-57
lines changed

.vscode/tasks.json

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
{
2-
// See https://go.microsoft.com/fwlink/?LinkId=733558
3-
// for the documentation about the tasks.json format
42
"version": "2.0.0",
53
"tasks": [
64
{
@@ -90,7 +88,8 @@
9088
"Generate leaf.hpp",
9189
"Download nlohmann/json.hpp"
9290
],
93-
"command": "cd ${workspaceRoot}/_bld/debug && ninja && meson test && cd ${workspaceRoot}/_bld/debug && ninja && meson test",
91+
"dependsOrder": "sequence",
92+
"command": "cd ${workspaceRoot}/_bld/debug && ninja && meson test && cd ${workspaceRoot}/_bld/debug_single_header && ninja && meson test",
9493
"problemMatcher": {
9594
"base": "$gcc",
9695
"fileLocation": [
@@ -116,6 +115,7 @@
116115
"Generate leaf.hpp",
117116
"Download nlohmann/json.hpp"
118117
],
118+
"dependsOrder": "sequence",
119119
"command": "cd ${workspaceRoot}/_bld/release && ninja && meson test && cd ${workspaceRoot}/_bld/release_single_header && ninja && meson test",
120120
"problemMatcher": {
121121
"base": "$gcc",
@@ -142,6 +142,7 @@
142142
"Generate leaf.hpp",
143143
"Download nlohmann/json.hpp"
144144
],
145+
"dependsOrder": "sequence",
145146
"command": "../../b2 --abbreviate-paths test link=shared,static variant=debug,release,leaf_debug_diag0,leaf_release_diag0,leaf_debug_single_header,leaf_release_single_header,leaf_debug_embedded,leaf_release_embedded exception-handling=off rtti=off cxxstd=11,14,1z,17 && ../../b2 --abbreviate-paths test link=shared,static variant=debug,release,leaf_debug_diag0,leaf_release_diag0,leaf_debug_single_header,leaf_release_single_header exception-handling=on,off cxxstd=11,14,1z,17",
146147
"problemMatcher": {
147148
"base": "$gcc",
@@ -168,10 +169,7 @@
168169
},
169170
"label": "Test current editor file",
170171
"type": "shell",
171-
"command": "cd ${workspaceRoot}/_bld/debug && ninja && { meson test ${fileBasenameNoExtension} || cat ./meson-logs/testlog.txt; }",,
172-
"windows": {
173-
"command": "cd ${workspaceRoot}/_bld/debug && ninja && (meson test ${fileBasenameNoExtension} || type .\\meson-logs\\testlog.txt)",
174-
},
172+
"command": "cd ${workspaceRoot}/_bld/debug && ninja && { meson test ${fileBasenameNoExtension} || cat ./meson-logs/testlog.txt; }",
175173
"problemMatcher": {
176174
"base": "$gcc",
177175
"fileLocation": [

doc/leaf.adoc

Lines changed: 94 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1813,28 +1813,28 @@ To support multiple output formats, pass multiple functions to `h.dispatch`:
18131813
[source,c++]
18141814
----
18151815
h.dispatch(
1816-
[&](nlohmann_writer & nw) { write_nested(nw, e, name); },
1816+
[&](json_writer_nlohmann & w) { write_nested(w, e, name); },
18171817
[&](xml_writer & xw) { write_nested(xw, e, name); }
18181818
);
18191819
----
18201820

18211821
==== JSON Serialization
18221822

1823-
LEAF provides `nlohmann_writer`, a class template for JSON serialization. The `nlohmann_writer` class defines `write` and `write_nested` friend functions (see <<tutorial-serialization>>) that work with:
1823+
LEAF provides writers for JSON serialization with two popular JSON libraries:
18241824

1825-
* Types for which `to_json` overloads can be found via ADL
1826-
* Types for which a `write` overload can be found via ADL (e.g. LEAF types)
1825+
* <<json_writer_nlohmann>> for https://github.com/nlohmann/json[nlohmann/json]
1826+
* <<json_writer_boost>> for https://www.boost.org/doc/libs/release/libs/json/[Boost.JSON]
18271827

1828-
This interface is compatible with https://github.com/nlohmann/json[nlohmann/json], we just need to define the required `serialize` function template (see <<custom-writers>>):
1828+
Below is an example using `json_writer_nlohmann`. We just need to define the required `serialize` function template (see <<custom-writers>>):
18291829

18301830
[source,c++]
18311831
----
1832-
#include <boost/leaf/serialization/nlohmann_writer.hpp>
1832+
#include <boost/leaf/serialization/json_writer_nlohmann.hpp>
18331833
#include "nlohmann/json.hpp"
18341834
18351835
namespace leaf = boost::leaf;
18361836
1837-
using nlohmann_writer = leaf::serialization::nlohmann_writer<nlohmann::json>;
1837+
using json_writer_nlohmann = leaf::serialization::json_writer_nlohmann<nlohmann::json>;
18381838
18391839
namespace boost { namespace leaf {
18401840
@@ -1843,8 +1843,8 @@ namespace serialization {
18431843
template <class Handle, class E>
18441844
void serialize(Handle & h, E const & e, char const * name)
18451845
{
1846-
h.dispatch([&](nlohmann_writer & nw) {
1847-
write_nested(nw, e, name);
1846+
h.dispatch([&](json_writer_nlohmann & w) {
1847+
write_nested(w, e, name);
18481848
});
18491849
}
18501850
@@ -1886,7 +1886,7 @@ leaf::try_handle_all(
18861886
[](leaf::diagnostic_details const & dd)
18871887
{
18881888
nlohmann::json j;
1889-
nlohmann_writer w(j);
1889+
json_writer_nlohmann w(j);
18901890
dd.write_to(w);
18911891
std::cout << j.dump(2) << std::endl;
18921892
}
@@ -2867,36 +2867,68 @@ Reference: <<to_variant>>
28672867

28682868
=== Serialization
28692869

2870-
[[nlohmann_writer.hpp]]
2871-
==== `nlohmann_writer.hpp`
2870+
[[json_writer_boost.hpp]]
2871+
==== `json_writer_boost.hpp`
28722872

28732873
====
2874-
.#include <boost/leaf/serialization/nlohmann_writer.hpp>
2874+
.#include <boost/leaf/serialization/json_writer_boost.hpp>
2875+
[source,c++]
2876+
----
2877+
namespace boost { namespace leaf {
2878+
2879+
namespace serialization
2880+
{
2881+
struct json_writer_boost
2882+
{
2883+
boost::json::value & v_;
2884+
2885+
// Enabled if x is assignable to boost::json::value, or
2886+
// if tag_invoke is defined for boost::json::value_from_tag.
2887+
template <class T>
2888+
friend void write( json_writer_boost &, T const & x );
2889+
2890+
template <class T>
2891+
friend void write_nested( json_writer_boost &, T const &, char const * name );
2892+
};
2893+
}
2894+
2895+
} }
2896+
----
2897+
2898+
[.text-right]
2899+
Reference: <<json_writer_boost>>
2900+
====
2901+
2902+
[[json_writer_nlohmann.hpp]]
2903+
==== `json_writer_nlohmann.hpp`
2904+
2905+
====
2906+
.#include <boost/leaf/serialization/json_writer_nlohmann.hpp>
28752907
[source,c++]
28762908
----
28772909
namespace boost { namespace leaf {
28782910
28792911
namespace serialization
28802912
{
28812913
template <class Json>
2882-
struct nlohmann_writer
2914+
struct json_writer_nlohmann
28832915
{
28842916
Json & j_;
28852917
2918+
// Enabled if to_json is defined for Json and T.
28862919
template <class T>
2887-
friend auto write( nlohmann_writer &, T const & x )
2888-
-> decltype(to_json(std::declval<Json &>(), x));
2920+
friend void write( json_writer_nlohmann &, T const & x );
28892921
28902922
template <class T>
2891-
friend void write_nested( nlohmann_writer &, T const &, char const * name );
2923+
friend void write_nested( json_writer_nlohmann &, T const &, char const * name );
28922924
};
28932925
}
28942926
28952927
} }
28962928
----
28972929
28982930
[.text-right]
2899-
Reference: <<nlohmann_writer>>
2931+
Reference: <<json_writer_nlohmann>>
29002932
====
29012933

29022934
[[functions]]
@@ -4442,36 +4474,70 @@ The `write_to` member function is used with the serialization system; see <<tuto
44424474

44434475
'''
44444476

4445-
[[nlohmann_writer]]
4446-
=== `nlohmann_writer`
4477+
[[json_writer_boost]]
4478+
=== `json_writer_boost`
4479+
4480+
.#include <boost/leaf/serialization/json_writer_boost.hpp>
4481+
[source,c++]
4482+
----
4483+
namespace boost { namespace leaf {
4484+
4485+
namespace serialization
4486+
{
4487+
struct json_writer_boost
4488+
{
4489+
boost::json::value & v_;
4490+
4491+
// Enabled if x is assignable to boost::json::value, or
4492+
// if tag_invoke is defined for boost::json::value_from_tag.
4493+
template <class T>
4494+
friend void write( json_writer_boost &, T const & x );
4495+
4496+
template <class T>
4497+
friend void write_nested( json_writer_boost &, T const &, char const * name );
4498+
};
4499+
}
4500+
4501+
} }
4502+
----
4503+
4504+
The `json_writer_boost` type serializes error objects to JSON format using https://www.boost.org/doc/libs/release/libs/json/[Boost.JSON]. The `write` function is enabled for:
4505+
4506+
* Types directly assignable to `boost::json::value`
4507+
* Types for which a `tag_invoke` overload for `value_from_tag` can be found via ADL
4508+
4509+
See <<tutorial-serialization>>.
4510+
4511+
'''
4512+
4513+
[[json_writer_nlohmann]]
4514+
=== `json_writer_nlohmann`
44474515

4448-
.#include <boost/leaf/serialization/nlohmann_writer.hpp>
4516+
.#include <boost/leaf/serialization/json_writer_nlohmann.hpp>
44494517
[source,c++]
44504518
----
44514519
namespace boost { namespace leaf {
44524520
44534521
namespace serialization
44544522
{
44554523
template <class Json>
4456-
struct nlohmann_writer
4524+
struct json_writer_nlohmann
44574525
{
44584526
Json & j_;
44594527
4460-
// Enabled for types for which a suitable to_json overload
4461-
// can be found via ADL, but a suitable write overload cannot.
4528+
// Enabled if to_json is defined for Json and T.
44624529
template <class T>
4463-
friend auto write( nlohmann_writer &, T const & x )
4464-
-> decltype(to_json(std::declval<Json &>(), x));
4530+
friend void write( json_writer_nlohmann &, T const & x );
44654531
44664532
template <class T>
4467-
friend void write_nested( nlohmann_writer &, T const &, char const * name );
4533+
friend void write_nested( json_writer_nlohmann &, T const &, char const * name );
44684534
};
44694535
}
44704536
44714537
} }
44724538
----
44734539

4474-
The `nlohmann_writer` class template serializes error objects to JSON format using unqualified calls to `to_json`. This is compatible with https://github.com/nlohmann/json[nlohmann/json]; See <<tutorial-serialization>>.
4540+
The `json_writer_nlohmann` serializes error objects to JSON format using unqualified calls to `to_json`. This is compatible with https://github.com/nlohmann/json[nlohmann/json]; See <<tutorial-serialization>>.
44754541

44764542
'''
44774543

include/boost/leaf/detail/all.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@
1111
#include <boost/leaf/on_error.hpp>
1212
#include <boost/leaf/pred.hpp>
1313
#include <boost/leaf/result.hpp>
14-
#include <boost/leaf/serialization/nlohmann_writer.hpp>
14+
#include <boost/leaf/serialization/json_writer_boost.hpp>
15+
#include <boost/leaf/serialization/json_writer_nlohmann.hpp>
1516
#include <boost/leaf/to_variant.hpp>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#ifndef BOOST_LEAF_SERIALIZATION_JSON_WRITER_BOOST_HPP_INCLUDED
2+
#define BOOST_LEAF_SERIALIZATION_JSON_WRITER_BOOST_HPP_INCLUDED
3+
4+
// Copyright 2018-2026 Emil Dotchevski and Reverge Studios, Inc.
5+
// Distributed under the Boost Software License, Version 1.0. (See accompanying
6+
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7+
8+
#include <utility>
9+
10+
namespace boost { namespace json {
11+
12+
class value;
13+
struct value_from_tag;
14+
15+
} }
16+
17+
namespace boost { namespace leaf {
18+
19+
namespace serialization
20+
{
21+
template <class Value = boost::json::value, class ValueFromTag = boost::json::value_from_tag>
22+
struct json_writer_boost_
23+
{
24+
Value & v_;
25+
26+
template <class T>
27+
friend auto write(json_writer_boost_ & w, T const & x) -> decltype(std::declval<Value &>() = x, void())
28+
{
29+
w.v_ = x;
30+
}
31+
32+
template <class T>
33+
friend auto write(json_writer_boost_ & w, T const & x) -> decltype(tag_invoke(std::declval<ValueFromTag>(), std::declval<Value &>(), x), void())
34+
{
35+
tag_invoke(ValueFromTag{}, w.v_, x);
36+
}
37+
38+
template <class T>
39+
friend void write_nested(json_writer_boost_ & w, T const & x, char const * name)
40+
{
41+
if( w.v_.is_null() )
42+
w.v_.emplace_object();
43+
json_writer_boost_ nested{w.v_.as_object()[name]};
44+
write(nested, x);
45+
}
46+
};
47+
48+
using json_writer_boost = json_writer_boost_<>;
49+
}
50+
51+
} }
52+
53+
#endif

include/boost/leaf/serialization/nlohmann_writer.hpp renamed to include/boost/leaf/serialization/json_writer_nlohmann.hpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
#ifndef BOOST_LEAF_SERIALIZATION_NLOHMANN_WRITER_HPP_INCLUDED
2-
#define BOOST_LEAF_SERIALIZATION_NLOHMANN_WRITER_HPP_INCLUDED
1+
#ifndef BOOST_LEAF_SERIALIZATION_JSON_WRITER_NLOHMANN_HPP_INCLUDED
2+
#define BOOST_LEAF_SERIALIZATION_JSON_WRITER_NLOHMANN_HPP_INCLUDED
33

44
// Copyright 2018-2026 Emil Dotchevski and Reverge Studios, Inc.
55
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -12,26 +12,25 @@ namespace boost { namespace leaf {
1212
namespace serialization
1313
{
1414
template <class Json>
15-
struct nlohmann_writer
15+
struct json_writer_nlohmann
1616
{
1717
Json & j_;
1818

1919
template <class T>
20-
friend auto write(nlohmann_writer & w, T const & x) -> decltype(to_json(std::declval<Json &>(), x))
20+
friend auto write(json_writer_nlohmann & w, T const & x) -> decltype(to_json(std::declval<Json &>(), x), void())
2121
{
2222
to_json(w.j_, x);
2323
}
2424

2525
template <class T>
26-
friend void write_nested(nlohmann_writer & w, T const & x, char const * name)
26+
friend void write_nested(json_writer_nlohmann & w, T const & x, char const * name)
2727
{
28-
nlohmann_writer nested{w.j_[name]};
28+
json_writer_nlohmann nested{w.j_[name]};
2929
write(nested, x);
3030
}
3131
};
32-
3332
}
3433

3534
} }
3635

37-
#endif // #ifndef BOOST_LEAF_SERIALIZATION_NLOHMANN_WRITER_HPP_INCLUDED
36+
#endif

meson.build

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ if option_enable_unit_tests
141141
'handle_basic_test',
142142
'handle_some_other_result_test',
143143
'handle_some_test',
144-
'nlohmann_test',
144+
'json_writer_nlohmann_test',
145145
'match_member_test',
146146
'match_test',
147147
'match_value_test',
@@ -224,7 +224,7 @@ if option_enable_unit_tests
224224
'_hpp_on_error_test',
225225
'_hpp_pred_test',
226226
'_hpp_result_test',
227-
'_hpp_serialization_nlohmann_writer_test',
227+
'_hpp_serialization_json_writer_nlohmann_test',
228228
'_hpp_to_variant_test',
229229
]
230230
foreach t : header_tests

test/Jamfile.v2

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ compile _hpp_leaf_test.cpp ;
4444
compile _hpp_on_error_test.cpp ;
4545
compile _hpp_pred_test.cpp ;
4646
compile _hpp_result_test.cpp ;
47-
compile _hpp_serialization_nlohmann_writer_test.cpp ;
47+
compile _hpp_serialization_json_writer_nlohmann_test.cpp ;
48+
compile _hpp_serialization_json_writer_boost_test.cpp ;
4849
compile _hpp_to_variant_test.cpp ;
4950

5051
run boost_exception_test.cpp ;
@@ -84,7 +85,8 @@ run handle_all_test.cpp ;
8485
run handle_basic_test.cpp ;
8586
run handle_some_other_result_test.cpp ;
8687
run handle_some_test.cpp ;
87-
run nlohmann_test.cpp : : : <toolset>clang,<target-os>linux,<cxxstd>2b:<build>no <toolset>clang,<target-os>linux,<cxxstd>23:<build>no ;
88+
run json_writer_nlohmann_test.cpp : : : <toolset>clang,<target-os>linux,<cxxstd>2b:<build>no <toolset>clang,<target-os>linux,<cxxstd>23:<build>no ;
89+
run json_writer_boost_test.cpp /boost/json//boost_json ;
8890
run match_member_test.cpp ;
8991
run match_test.cpp ;
9092
run match_value_test.cpp ;

0 commit comments

Comments
 (0)