Skip to content

Commit

Permalink
Added documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
liuzicheng1987 committed Nov 9, 2024
1 parent 52f0fd2 commit 267792f
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 5 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ The following table lists the serialization formats currently supported by refle
| flexbuffers | [flatbuffers](https://github.com/google/flatbuffers) | >= 23.5.26 | Apache 2.0 | Schema-less version of flatbuffers, binary format |
| msgpack | [msgpack-c](https://github.com/msgpack/msgpack-c) | >= 6.0.0 | BSL 1.0 | JSON-like binary format |
| TOML | [toml++](https://github.com/marzer/tomlplusplus) | >= 3.4.0 | MIT | Textual format with an emphasis on readability |
| UBJSON | [jsoncons](https://github.com/danielaparker/jsoncons)| >= 0.176.0 | BSL 1.0 | JSON-like binary format |
| XML | [pugixml](https://github.com/zeux/pugixml) | >= 1.14 | MIT | Textual format used in many legacy projects |
| YAML | [yaml-cpp](https://github.com/jbeder/yaml-cpp) | >= 0.8.0 | MIT | Textual format with an emphasis on readability |

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

```bash
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
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
cmake --build build -j 4 # gcc, clang
cmake --build build --config Release -j 4 # MSVC
```
Expand All @@ -633,6 +635,7 @@ To run the tests, do the following:
./build/tests/msgpack/reflect-cpp-msgpack-tests
./build/tests/json/reflect-cpp-json-tests
./build/tests/toml/reflect-cpp-toml-tests
./build/tests/toml/reflect-cpp-ubjson-tests
./build/tests/xml/reflect-cpp-xml-tests
./build/tests/yaml/reflect-cpp-yaml-tests
```
Expand Down
6 changes: 4 additions & 2 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,11 @@

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

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

6.8) [YAML](https://github.com/getml/reflect-cpp/blob/main/docs/yaml.md)
6.8) [XML](https://github.com/getml/reflect-cpp/blob/main/docs/xml.md)

6.9) [YAML](https://github.com/getml/reflect-cpp/blob/main/docs/yaml.md)

## 7) Advanced topics

Expand Down
2 changes: 1 addition & 1 deletion docs/cbor.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ struct Person {
};
```
A `Person` can be turned into a bytes vector like this:
A `Person` can be serialized to a bytes vector like this:
```cpp
const auto person = Person{...};
Expand Down
100 changes: 100 additions & 0 deletions docs/ubjson.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# UBJSON

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.

UBJSON is a JSON-like binary format.

## Reading and writing

Suppose you have a struct like this:

```cpp
struct Person {
std::string first_name;
std::string last_name;
rfl::Timestamp<"%Y-%m-%d"> birthday;
std::vector<Person> children;
};
```
A `Person` can be serialized to a bytes vector like this:
```cpp
const auto person = Person{...};
const std::vector<char> bytes = rfl::ubjson::write(person);
```

You can parse bytes like this:

```cpp
const rfl::Result<Person> result = rfl::ubjson::read<Person>(bytes);
```

## Loading and saving

You can also load and save to disc using a very similar syntax:

```cpp
const rfl::Result<Person> result = rfl::ubjson::load<Person>("/path/to/file.ubjson");

const auto person = Person{...};
rfl::ubjson::save("/path/to/file.ubjson", person);
```
## Reading from and writing into streams
You can also read from and write into any `std::istream` and `std::ostream` respectively.
```cpp
const rfl::Result<Person> result = rfl::ubjson::read<Person>(my_istream);
const auto person = Person{...};
rfl::ubjson::write(person, my_ostream);
```

Note that `std::cout` is also an ostream, so this works as well:

```cpp
rfl::ubjson::write(person, std::cout) << std::endl;
```
(Since UBJSON is a binary format, the readability of this will be limited, but it might be useful for debugging).
## Custom constructors
One of the great things about C++ is that it gives you control over
when and how you code is compiled.
For large and complex systems of structs, it is often a good idea to split up
your code into smaller compilation units. You can do so using custom constructors.
For the UBJSON format, these must be a static function on your struct or class called
`from_ubjson` that take a `rfl::ubjson::Reader::InputVarType` as input and return
the class or the class wrapped in `rfl::Result`.
In your header file you can write something like this:
```cpp
struct Person {
rfl::Rename<"firstName", std::string> first_name;
rfl::Rename<"lastName", std::string> last_name;
rfl::Timestamp<"%Y-%m-%d"> birthday;
using InputVarType = typename rfl::ubjson::Reader::InputVarType;
static rfl::Result<Person> from_ubjson(const InputVarType& _obj);
};
```

And in your source file, you implement `from_ubjson` as follows:

```cpp
rfl::Result<Person> Person::from_ubjson(const InputVarType& _obj) {
const auto from_nt = [](auto&& _nt) {
return rfl::from_named_tuple<Person>(std::move(_nt));
};
return rfl::ubjson::read<rfl::named_tuple_t<Person>>(_obj)
.transform(from_nt);
}
```
This will force the compiler to only compile the UBJSON parsing when the source file is compiled.

0 comments on commit 267792f

Please sign in to comment.