Skip to content

Commit 267792f

Browse files
Added documentation
1 parent 52f0fd2 commit 267792f

File tree

4 files changed

+110
-5
lines changed

4 files changed

+110
-5
lines changed

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ The following table lists the serialization formats currently supported by refle
3636
| flexbuffers | [flatbuffers](https://github.com/google/flatbuffers) | >= 23.5.26 | Apache 2.0 | Schema-less version of flatbuffers, binary format |
3737
| msgpack | [msgpack-c](https://github.com/msgpack/msgpack-c) | >= 6.0.0 | BSL 1.0 | JSON-like binary format |
3838
| TOML | [toml++](https://github.com/marzer/tomlplusplus) | >= 3.4.0 | MIT | Textual format with an emphasis on readability |
39+
| UBJSON | [jsoncons](https://github.com/danielaparker/jsoncons)| >= 0.176.0 | BSL 1.0 | JSON-like binary format |
3940
| XML | [pugixml](https://github.com/zeux/pugixml) | >= 1.14 | MIT | Textual format used in many legacy projects |
4041
| YAML | [yaml-cpp](https://github.com/jbeder/yaml-cpp) | >= 0.8.0 | MIT | Textual format with an emphasis on readability |
4142

@@ -471,7 +472,7 @@ In addition, it supports the following custom containers:
471472
472473
- `rfl::Binary`: Used to express numbers in binary format.
473474
- `rfl::Box`: Similar to `std::unique_ptr`, but (almost) guaranteed to never be null.
474-
- `rfl::Bytestring`: An alias for `std::basic_string<std::byte>`. Supported by BSON, CBOR, flexbuffers and msgpack.
475+
- `rfl::Bytestring`: An alias for `std::basic_string<std::byte>`. Supported by BSON, CBOR, flexbuffers, msgpack and UBJSON.
475476
- `rfl::Generic`: A catch-all type that can represent (almost) anything.
476477
- `rfl::Hex`: Used to express numbers in hex format.
477478
- `rfl::Literal`: An explicitly enumerated string.
@@ -569,6 +570,7 @@ set(REFLECTCPP_CBOR ON) # Optional
569570
set(REFLECTCPP_FLEXBUFFERS ON) # Optional
570571
set(REFLECTCPP_MSGPACK ON) # Optional
571572
set(REFLECTCPP_TOML ON) # Optional
573+
set(REFLECTCPP_UBJSON ON) # Optional
572574
set(REFLECTCPP_XML ON) # Optional
573575
set(REFLECTCPP_YAML ON) # Optional
574576
@@ -619,7 +621,7 @@ To run the tests, do the following:
619621
To compile the tests with serialization formats other than JSON, do the following:
620622

621623
```bash
622-
cmake -S . -B build -DREFLECTCPP_BUILD_TESTS=ON -DREFLECTCPP_BSON=ON -DREFLECTCPP_CBOR=ON -DREFLECTCPP_FLEXBUFFERS=ON -DREFLECTCPP_MSGPACK=ON -DREFLECTCPP_XML=ON -DREFLECTCPP_TOML=ON -DREFLECTCPP_YAML=ON -DCMAKE_BUILD_TYPE=Release
624+
cmake -S . -B build -DREFLECTCPP_BUILD_TESTS=ON -DREFLECTCPP_BSON=ON -DREFLECTCPP_CBOR=ON -DREFLECTCPP_FLEXBUFFERS=ON -DREFLECTCPP_MSGPACK=ON -DREFLECTCPP_XML=ON -DREFLECTCPP_TOML=ON -DREFLECTCPP_UBJSON=ON -DREFLECTCPP_YAML=ON -DCMAKE_BUILD_TYPE=Release
623625
cmake --build build -j 4 # gcc, clang
624626
cmake --build build --config Release -j 4 # MSVC
625627
```
@@ -633,6 +635,7 @@ To run the tests, do the following:
633635
./build/tests/msgpack/reflect-cpp-msgpack-tests
634636
./build/tests/json/reflect-cpp-json-tests
635637
./build/tests/toml/reflect-cpp-toml-tests
638+
./build/tests/toml/reflect-cpp-ubjson-tests
636639
./build/tests/xml/reflect-cpp-xml-tests
637640
./build/tests/yaml/reflect-cpp-yaml-tests
638641
```

docs/README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,11 @@
8888

8989
6.6) [TOML](https://github.com/getml/reflect-cpp/blob/main/docs/toml.md)
9090

91-
6.7) [XML](https://github.com/getml/reflect-cpp/blob/main/docs/xml.md)
91+
6.7) [UBJSON](https://github.com/getml/reflect-cpp/blob/main/docs/ubjson.md)
9292

93-
6.8) [YAML](https://github.com/getml/reflect-cpp/blob/main/docs/yaml.md)
93+
6.8) [XML](https://github.com/getml/reflect-cpp/blob/main/docs/xml.md)
94+
95+
6.9) [YAML](https://github.com/getml/reflect-cpp/blob/main/docs/yaml.md)
9496

9597
## 7) Advanced topics
9698

docs/cbor.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ struct Person {
1717
};
1818
```
1919
20-
A `Person` can be turned into a bytes vector like this:
20+
A `Person` can be serialized to a bytes vector like this:
2121
2222
```cpp
2323
const auto person = Person{...};

docs/ubjson.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# UBJSON
2+
3+
For UBJSON support, you must also include the header `<rfl/ubjson.hpp>` and include the jsoncons library (https://github.com/danielaparker/jsoncons). Note that it is header-only.
4+
5+
UBJSON is a JSON-like binary format.
6+
7+
## Reading and writing
8+
9+
Suppose you have a struct like this:
10+
11+
```cpp
12+
struct Person {
13+
std::string first_name;
14+
std::string last_name;
15+
rfl::Timestamp<"%Y-%m-%d"> birthday;
16+
std::vector<Person> children;
17+
};
18+
```
19+
20+
A `Person` can be serialized to a bytes vector like this:
21+
22+
```cpp
23+
const auto person = Person{...};
24+
const std::vector<char> bytes = rfl::ubjson::write(person);
25+
```
26+
27+
You can parse bytes like this:
28+
29+
```cpp
30+
const rfl::Result<Person> result = rfl::ubjson::read<Person>(bytes);
31+
```
32+
33+
## Loading and saving
34+
35+
You can also load and save to disc using a very similar syntax:
36+
37+
```cpp
38+
const rfl::Result<Person> result = rfl::ubjson::load<Person>("/path/to/file.ubjson");
39+
40+
const auto person = Person{...};
41+
rfl::ubjson::save("/path/to/file.ubjson", person);
42+
```
43+
44+
## Reading from and writing into streams
45+
46+
You can also read from and write into any `std::istream` and `std::ostream` respectively.
47+
48+
```cpp
49+
const rfl::Result<Person> result = rfl::ubjson::read<Person>(my_istream);
50+
51+
const auto person = Person{...};
52+
rfl::ubjson::write(person, my_ostream);
53+
```
54+
55+
Note that `std::cout` is also an ostream, so this works as well:
56+
57+
```cpp
58+
rfl::ubjson::write(person, std::cout) << std::endl;
59+
```
60+
61+
(Since UBJSON is a binary format, the readability of this will be limited, but it might be useful for debugging).
62+
63+
## Custom constructors
64+
65+
One of the great things about C++ is that it gives you control over
66+
when and how you code is compiled.
67+
68+
For large and complex systems of structs, it is often a good idea to split up
69+
your code into smaller compilation units. You can do so using custom constructors.
70+
71+
For the UBJSON format, these must be a static function on your struct or class called
72+
`from_ubjson` that take a `rfl::ubjson::Reader::InputVarType` as input and return
73+
the class or the class wrapped in `rfl::Result`.
74+
75+
In your header file you can write something like this:
76+
77+
```cpp
78+
struct Person {
79+
rfl::Rename<"firstName", std::string> first_name;
80+
rfl::Rename<"lastName", std::string> last_name;
81+
rfl::Timestamp<"%Y-%m-%d"> birthday;
82+
83+
using InputVarType = typename rfl::ubjson::Reader::InputVarType;
84+
static rfl::Result<Person> from_ubjson(const InputVarType& _obj);
85+
};
86+
```
87+
88+
And in your source file, you implement `from_ubjson` as follows:
89+
90+
```cpp
91+
rfl::Result<Person> Person::from_ubjson(const InputVarType& _obj) {
92+
const auto from_nt = [](auto&& _nt) {
93+
return rfl::from_named_tuple<Person>(std::move(_nt));
94+
};
95+
return rfl::ubjson::read<rfl::named_tuple_t<Person>>(_obj)
96+
.transform(from_nt);
97+
}
98+
```
99+
100+
This will force the compiler to only compile the UBJSON parsing when the source file is compiled.

0 commit comments

Comments
 (0)