Skip to content

Commit c496fd3

Browse files
committed
README extended with a new example for Reader_Writer.
1 parent 837b036 commit c496fd3

File tree

1 file changed

+110
-6
lines changed

1 file changed

+110
-6
lines changed

README.md

+110-6
Original file line numberDiff line numberDiff line change
@@ -1818,8 +1818,7 @@ struct numeric_log_level
18181818
v = static_cast<log_level>(actual);
18191819
}
18201820

1821-
void
1822-
write(
1821+
void write(
18231822
const log_level & v,
18241823
rapidjson::Value & to,
18251824
rapidjson::MemoryPoolAllocator<> & allocator ) const
@@ -1859,8 +1858,7 @@ struct textual_log_level
18591858
else throw json_dto::ex_t{ "invalid value for log_level" };
18601859
}
18611860

1862-
void
1863-
write(
1861+
void write(
18641862
const log_level & v,
18651863
rapidjson::Value & to,
18661864
rapidjson::MemoryPoolAllocator<> & allocator ) const
@@ -1940,8 +1938,7 @@ struct custom_floating_point_reader_writer
19401938
}
19411939
19421940
template< typename T >
1943-
void
1944-
write(
1941+
void write(
19451942
T & v,
19461943
rapidjson::Value & to,
19471944
rapidjson::MemoryPoolAllocator<> & allocator ) const
@@ -1980,6 +1977,113 @@ struct struct_with_floats_t
19801977

19811978
Note also that `read` and `write` methods of Reader_Writer class can be template methods.
19821979

1980+
A custom Reader_Writer can also be used to change representation of a field. For example, let suppose that we have a `std::vector<some_struct>` field, but this field has to be represented as a single object if it holds just one value, and as an array otherwise. Something like:
1981+
1982+
```json
1983+
{
1984+
"message": {
1985+
"from": "address-1",
1986+
"to": "address-2",
1987+
...,
1988+
"extension": {...}
1989+
},
1990+
...
1991+
}
1992+
```
1993+
1994+
if we have only one extension in a message or:
1995+
1996+
```json
1997+
{
1998+
"message": {
1999+
"from": "address-1",
2000+
"to": "address-2",
2001+
...,
2002+
"extension": [
2003+
{...},
2004+
{...},
2005+
...
2006+
]
2007+
},
2008+
...
2009+
}
2010+
```
2011+
2012+
if there are several extensions.
2013+
2014+
A solution with a custom Reader_Writer can looks like:
2015+
2016+
```cpp
2017+
struct extension
2018+
{
2019+
...
2020+
2021+
template< typename Json_Io >
2022+
void json_io( Json_Io & io )
2023+
{
2024+
... // Ordinary serialization/deserialization code.
2025+
}
2026+
};
2027+
2028+
// Reader_Writer for vector of `extension` objects.
2029+
struct extension_reader_writer
2030+
{
2031+
void read( std::vector< extension > & to, const rapidjson::Value & from ) const
2032+
{
2033+
using json_dto::read_json_value;
2034+
2035+
to.clear();
2036+
2037+
if( from.IsObject() )
2038+
{
2039+
extension_t single_value;
2040+
read_json_value( single_value, from );
2041+
to.push_back( std::move(single_value) );
2042+
}
2043+
else if( from.IsArray() )
2044+
{
2045+
read_json_value( to, from );
2046+
}
2047+
else
2048+
{
2049+
throw std::runtime_error{ "Unexpected format of extension value" };
2050+
}
2051+
}
2052+
2053+
void write(
2054+
const std::vector< extension > & v,
2055+
rapidjson::Value & to,
2056+
rapidjson::MemoryPoolAllocator<> & allocator ) const
2057+
{
2058+
using json_dto::write_json_value;
2059+
if( 1u == v.size() )
2060+
write_json_value( v.front(), to, allocator );
2061+
else
2062+
write_json_value( v, to, allocator );
2063+
}
2064+
};
2065+
2066+
// Message.
2067+
struct message
2068+
{
2069+
// Fields of a message.
2070+
...
2071+
// Extension(s) for a message.
2072+
std::vector< extension > m_extension;
2073+
2074+
template< typename Json_Io >
2075+
void json_io( Json_Io & io )
2076+
{
2077+
io & ...
2078+
& json_dto::mandatory( extension_reader_writer{},
2079+
"extension", m_extension )
2080+
;
2081+
}
2082+
};
2083+
```
2084+
2085+
The full example of such an approach can be seen [here](./dev/sample/tutorial18.1/main.cpp)
2086+
19832087
#### Custom Reader_Writer with containers and nullable_t, and std::optional
19842088
19852089
If a custom Reader_Writer is used then a reference to the whole field is passed to Reader_Writer's methods. For example:

0 commit comments

Comments
 (0)