Skip to content

Commit 4eda81a

Browse files
committed
add boost_json_serializer to replace rapid json one
1 parent 11ebd1e commit 4eda81a

File tree

6 files changed

+267
-7
lines changed

6 files changed

+267
-7
lines changed

include/jinja2cpp/generic_list.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66

77
#include <nonstd/optional.hpp>
88

9+
#include <functional>
910
#include <iterator>
1011
#include <memory>
11-
#include <functional>
1212

1313
namespace jinja2
1414
{

include/jinja2cpp/reflected_value.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55

66
#include <nonstd/optional.hpp>
77

8-
#include <vector>
9-
#include <set>
108
#include <cstddef>
9+
#include <memory>
10+
#include <set>
1111
#include <string>
1212
#include <type_traits>
13-
#include <memory>
13+
#include <vector>
1414

1515
namespace jinja2
1616
{

include/jinja2cpp/string_helpers.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
#ifndef JINJA2CPP_STRING_HELPERS_H
22
#define JINJA2CPP_STRING_HELPERS_H
33

4-
#include <nonstd/string_view.hpp>
54
#include "value.h"
65

6+
#include <nonstd/string_view.hpp>
7+
8+
#include <cwchar>
79
#include <string>
810
#include <type_traits>
9-
#include <cwchar>
1011

1112
namespace jinja2
1213
{
@@ -292,4 +293,4 @@ inline std::wstring AsWString(const Value& val)
292293
}
293294
} // namespace jinja2
294295

295-
#endif // JINJA2CPP_STRING_HELPERS_H
296+
#endif // JINJA2CPP_STRING_HELPERS_H

src/binding/boost_json_serializer.cpp

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
#include "boost_json_serializer.h"
2+
3+
#include "../value_visitors.h"
4+
5+
// #include <boost::json/prettywriter.h>
6+
7+
namespace jinja2
8+
{
9+
namespace boost_json_serializer
10+
{
11+
namespace
12+
{
13+
struct JsonInserter : visitors::BaseVisitor<boost::json::value>
14+
{
15+
using BaseVisitor::operator();
16+
17+
explicit JsonInserter() {}
18+
19+
boost::json::value operator()(const ListAdapter& list) const
20+
{
21+
boost::json::array listValue; //(boost::json::kind::array);
22+
23+
for (auto& v : list)
24+
{
25+
listValue.push_back(Apply<JsonInserter>(v));
26+
}
27+
return listValue;
28+
}
29+
30+
boost::json::value operator()(const MapAdapter& map) const
31+
{
32+
boost::json::object mapNode; //(boost::json::kind::object);
33+
34+
const auto& keys = map.GetKeys();
35+
for (auto& k : keys)
36+
{
37+
mapNode.emplace(k.c_str(), Apply<JsonInserter>(map.GetValueByName(k)));
38+
}
39+
40+
return mapNode;
41+
}
42+
43+
boost::json::value operator()(const KeyValuePair& kwPair) const
44+
{
45+
boost::json::object pairNode; //(boost::json::kind::object);
46+
pairNode.emplace(kwPair.key.c_str(), Apply<JsonInserter>(kwPair.value));
47+
48+
return pairNode;
49+
}
50+
51+
boost::json::value operator()(const std::string& str) const { return boost::json::value(str.c_str()); }
52+
53+
boost::json::value operator()(const nonstd::string_view& str) const
54+
{
55+
return boost::json::value(boost::json::string(str));
56+
// str.data(), static_cast<std::size_t>(str.size()));
57+
}
58+
59+
boost::json::value operator()(const std::wstring& str) const
60+
{
61+
auto s = ConvertString<std::string>(str);
62+
return boost::json::value(s.c_str());
63+
}
64+
65+
boost::json::value operator()(const nonstd::wstring_view& str) const
66+
{
67+
auto s = ConvertString<std::string>(str);
68+
return boost::json::value(s.c_str());
69+
}
70+
71+
boost::json::value operator()(bool val) const { return boost::json::value(val); }
72+
73+
boost::json::value operator()(EmptyValue) const { return boost::json::value(); }
74+
75+
boost::json::value operator()(const Callable&) const { return boost::json::value("<callable>"); }
76+
77+
boost::json::value operator()(double val) const { return boost::json::value(val); }
78+
79+
boost::json::value operator()(int64_t val) const { return boost::json::value(val); }
80+
81+
// boost::json::Document::AllocatorType& m_allocator;
82+
};
83+
} // namespace
84+
85+
DocumentWrapper::DocumentWrapper()
86+
// : m_document(std::make_shared<boost::json::Document>())
87+
{
88+
}
89+
90+
ValueWrapper DocumentWrapper::CreateValue(const InternalValue& value) const
91+
{
92+
auto v = Apply<JsonInserter>(value);
93+
return ValueWrapper(std::move(v));
94+
}
95+
96+
ValueWrapper::ValueWrapper(boost::json::value&& value)
97+
: m_value(std::move(value))
98+
{
99+
}
100+
101+
void PrettyPrint(std::ostream& os, const boost::json::value& jv, uint8_t indent = 4, std::string* indentString = nullptr)
102+
{
103+
std::string indentString_;
104+
if (!indentString)
105+
indentString = &indentString_;
106+
switch (jv.kind())
107+
{
108+
case boost::json::kind::object:
109+
{
110+
os << "{\n";
111+
indentString->append(indent, ' ');
112+
auto const& obj = jv.get_object();
113+
if (!obj.empty())
114+
{
115+
auto it = obj.begin();
116+
for (;;)
117+
{
118+
os << *indentString << boost::json::serialize(it->key()) << " : ";
119+
PrettyPrint(os, it->value(), indent, indentString);
120+
if (++it == obj.end())
121+
break;
122+
os << ",\n";
123+
}
124+
}
125+
os << "\n";
126+
indentString->resize(indentString->size() - indent);
127+
os << *indentString << "}";
128+
break;
129+
}
130+
131+
case boost::json::kind::array:
132+
{
133+
//os << "[\n";
134+
os << "[";
135+
indentString->append(1, ' ');
136+
auto const& arr = jv.get_array();
137+
if (!arr.empty())
138+
{
139+
auto it = arr.begin();
140+
for (;;)
141+
{
142+
os << ((it == arr.begin()) ? "" : *indentString);
143+
PrettyPrint(os, *it, indent, indentString);
144+
if (++it == arr.end())
145+
break;
146+
//os << ",\n";
147+
os << ",";
148+
}
149+
}
150+
//os << "\n";
151+
indentString->resize(indentString->size() - indent);
152+
os << *indentString << "]";
153+
break;
154+
}
155+
156+
case boost::json::kind::string:
157+
{
158+
os << boost::json::serialize(jv.get_string());
159+
break;
160+
}
161+
162+
case boost::json::kind::uint64:
163+
case boost::json::kind::int64:
164+
case boost::json::kind::double_:
165+
os << jv;
166+
break;
167+
168+
case boost::json::kind::bool_:
169+
if (jv.get_bool())
170+
os << "true";
171+
else
172+
os << "false";
173+
break;
174+
175+
case boost::json::kind::null:
176+
os << "null";
177+
break;
178+
}
179+
180+
//if (indentString->empty())
181+
// os << "\n";
182+
}
183+
184+
std::string ValueWrapper::AsString(const uint8_t indent) const
185+
{
186+
// using Writer = boost::json::Writer<boost::json::StringBuffer, boost::json::Document::EncodingType, boost::json::UTF8<>>;
187+
// using PrettyWriter = boost::json::PrettyWriter<boost::json::StringBuffer, boost::json::Document::EncodingType, boost::json::UTF8<>>;
188+
std::stringstream ss;
189+
PrettyPrint(ss, m_value, indent);
190+
return ss.str();
191+
/* boost::json::StringBuffer buffer; */
192+
/* if (indent == 0) */
193+
/* { */
194+
/* Writer writer(buffer); */
195+
/* m_value.Accept(writer); */
196+
/* } */
197+
/* else */
198+
/* { */
199+
/* PrettyWriter writer(buffer); */
200+
/* writer.SetIndent(' ', indent); */
201+
/* writer.SetFormatOptions(boost::json::kind::FormatSingleLineArray); */
202+
/* m_value.Accept(writer); */
203+
/* } */
204+
205+
/* return buffer.GetString(); */
206+
}
207+
208+
} // namespace boost_json_serializer
209+
} // namespace jinja2

src/binding/boost_json_serializer.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#ifndef JINJA2CPP_SRC_BOOST_JSON_SERIALIZER_H
2+
#define JINJA2CPP_SRC_BOOST_JSON_SERIALIZER_H
3+
4+
#include "../internal_value.h"
5+
6+
#include <boost/json.hpp>
7+
8+
#include <memory>
9+
10+
namespace jinja2
11+
{
12+
namespace boost_json_serializer
13+
{
14+
15+
class ValueWrapper
16+
{
17+
friend class DocumentWrapper;
18+
19+
public:
20+
ValueWrapper(ValueWrapper&&) = default;
21+
ValueWrapper& operator=(ValueWrapper&&) = default;
22+
23+
std::string AsString(uint8_t indent = 0) const;
24+
25+
private:
26+
ValueWrapper(boost::json::value&& value);
27+
28+
boost::json::value m_value;
29+
};
30+
31+
class DocumentWrapper
32+
{
33+
public:
34+
DocumentWrapper();
35+
36+
DocumentWrapper(DocumentWrapper&&) = default;
37+
DocumentWrapper& operator=(DocumentWrapper&&) = default;
38+
39+
ValueWrapper CreateValue(const InternalValue& value) const;
40+
41+
private:
42+
};
43+
44+
} // namespace boost_json_serializer
45+
} // namespace jinja2
46+
47+
#endif // JINJA2CPP_SRC_BOOST_JSON_SERIALIZER_H

src/serialize_filters.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "binding/rapid_json_serializer.h"
2+
#include "binding/boost_json_serializer.h"
23
#include "filters.h"
34
#include "generic_adapters.h"
45
#include "out_stream.h"
@@ -141,7 +142,9 @@ InternalValue Serialize::Filter(const InternalValue& value, RenderContext& conte
141142
if (m_mode == JsonMode)
142143
{
143144
const auto indent = ConvertToInt(this->GetArgumentValue("indent", context));
145+
144146
jinja2::rapidjson_serializer::DocumentWrapper jsonDoc;
147+
//jinja2::boost_json_serializer::DocumentWrapper jsonDoc;
145148
const auto jsonValue = jsonDoc.CreateValue(value);
146149
const auto jsonString = jsonValue.AsString(static_cast<uint8_t>(indent));
147150
const auto result = std::accumulate(jsonString.begin(), jsonString.end(), ""s, [](const auto &str, const auto &c)

0 commit comments

Comments
 (0)