Skip to content

Commit 5a34c9b

Browse files
Added BSON support; #22
1 parent 151e606 commit 5a34c9b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

82 files changed

+2267
-14
lines changed

Diff for: .github/workflows/test.yaml

+12-6
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ jobs:
66
linux-gcc:
77
runs-on: ubuntu-latest
88
steps:
9-
- uses: actions/checkout@v3
9+
- name: Checkout
10+
uses: actions/checkout@v3
1011
with:
11-
submodules: true
12+
submodules: recursive
13+
fetch-depth: 0
1214
- name: Run vcpkg
1315
uses: lukka/run-vcpkg@v11
1416
- name: install dependencies
@@ -18,8 +20,9 @@ jobs:
1820
- name: Run test
1921
run: |
2022
g++ --version
21-
cmake -S . -B build -DREFLECTCPP_BUILD_TESTS=ON -DREFLECTCPP_FLEXBUFFERS=ON -DREFLECTCPP_XML=ON -DREFLECTCPP_YAML=ON -DCMAKE_BUILD_TYPE=Release
23+
cmake -S . -B build -DREFLECTCPP_BUILD_TESTS=ON -DREFLECTCPP_BSON=ON -DREFLECTCPP_FLEXBUFFERS=ON -DREFLECTCPP_XML=ON -DREFLECTCPP_YAML=ON -DCMAKE_BUILD_TYPE=Release
2224
cmake --build build -j 4
25+
./build/tests/bson/reflect-cpp-bson-tests
2326
./build/tests/flexbuffers/reflect-cpp-flexbuffers-tests
2427
./build/tests/json/reflect-cpp-json-tests
2528
./build/tests/xml/reflect-cpp-xml-tests
@@ -28,9 +31,11 @@ jobs:
2831
linux-clang:
2932
runs-on: ubuntu-latest
3033
steps:
31-
- uses: actions/checkout@v3
34+
- name: Checkout
35+
uses: actions/checkout@v3
3236
with:
33-
submodules: true
37+
submodules: recursive
38+
fetch-depth: 0
3439
- name: Run vcpkg
3540
uses: lukka/run-vcpkg@v11
3641
- uses: KyleMayes/install-llvm-action@v1
@@ -47,8 +52,9 @@ jobs:
4752
CXX: clang++
4853
run: |
4954
clang --version
50-
cmake -S . -B build -DREFLECTCPP_BUILD_TESTS=ON -DREFLECTCPP_FLEXBUFFERS=ON -DREFLECTCPP_XML=ON -DREFLECTCPP_YAML=ON -DCMAKE_BUILD_TYPE=Release
55+
cmake -S . -B build -DREFLECTCPP_BUILD_TESTS=ON -DREFLECTCPP_BSON=ON -DREFLECTCPP_FLEXBUFFERS=ON -DREFLECTCPP_XML=ON -DREFLECTCPP_YAML=ON -DCMAKE_BUILD_TYPE=Release
5156
cmake --build build -j 4
57+
./build/tests/bson/reflect-cpp-bson-tests
5258
./build/tests/flexbuffers/reflect-cpp-flexbuffers-tests
5359
./build/tests/json/reflect-cpp-json-tests
5460
./build/tests/xml/reflect-cpp-xml-tests

Diff for: .gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
**/build_clang/**
4242

4343
# Output files
44+
*.bson
4445
*.json
4546
*.fb
4647
*.xml

Diff for: CMakeLists.txt

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
cmake_minimum_required(VERSION 3.15)
22

33
option(REFLECTCPP_BUILD_SHARED "Build shared library" OFF)
4+
option(REFLECTCPP_BSON "Enable BSON support" OFF)
45
option(REFLECTCPP_FLEXBUFFERS "Enable flexbuffers support" OFF)
56
option(REFLECTCPP_XML "Enable XML support" OFF)
67
option(REFLECTCPP_YAML "Enable YAML support" OFF)
78

89
option(REFLECTCPP_BUILD_TESTS "Build tests" OFF)
910

1011
# enable vcpkg if require features other than JSON
11-
if (REFLECTCPP_FLEXBUFFERS OR REFLECTCPP_XML OR REFLECTCPP_YAML)
12+
if (REFLECTCPP_BSON OR REFLECTCPP_FLEXBUFFERS OR REFLECTCPP_XML OR REFLECTCPP_YAML)
1213
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake CACHE STRING "Vcpkg toolchain file")
1314
endif ()
1415

@@ -24,6 +25,11 @@ endif ()
2425

2526
target_include_directories(reflectcpp PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
2627

28+
if (REFLECTCPP_BSON)
29+
find_package(bson-1.0 CONFIG REQUIRED)
30+
target_link_libraries(reflectcpp PRIVATE $<IF:$<TARGET_EXISTS:mongo::bson_static>,mongo::bson_static,mongo::bson_shared>)
31+
endif ()
32+
2733
if (REFLECTCPP_FLEXBUFFERS)
2834
find_package(flatbuffers CONFIG REQUIRED)
2935
target_link_libraries(reflectcpp INTERFACE flatbuffers::flatbuffers)

Diff for: README.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ The following table lists the serialization formats currently supported by refle
3131

3232
| Format | Library | Version | License | Remarks |
3333
|--------------|------------------------------------------------------|--------------|------------| -----------------------------------------------------|
34-
| JSON | [YYJSON](https://github.com/ibireme/yyjson) | >= 0.8.0 | MIT | out-of-the-box support, included in this repository |
34+
| JSON | [yyjson](https://github.com/ibireme/yyjson) | >= 0.8.0 | MIT | out-of-the-box support, included in this repository |
35+
| BSON | [libbson](https://github.com/mongodb/libbson) | >= 1.25.1 | Apache 2.0 | |
3536
| flexbuffers | [flatbuffers](https://github.com/google/flatbuffers) | >= 23.5.26 | Apache 2.0 | |
3637
| XML | [pugixml](https://github.com/zeux/pugixml) | >= 1.14 | MIT | |
3738
| YAML | [yaml-cpp](https://github.com/jbeder/yaml-cpp) | >= 0.8.0 | MIT | |
@@ -448,6 +449,7 @@ To use reflect-cpp in your project:
448449
```cmake
449450
add_subdirectory(reflect-cpp) # Add this project as a subdirectory
450451
452+
set(REFLECTCPP_BSON ON) # Optional
451453
set(REFLECTCPP_FLEXBUFFERS ON) # Optional
452454
set(REFLECTCPP_XML ON) # Optional
453455
set(REFLECTCPP_YAML ON) # Optional
@@ -494,7 +496,7 @@ git submodule update --init
494496
./vcpkg/bootstrap-vcpkg.bat # Windows
495497
# You may be prompted to install additional dependencies.
496498

497-
cmake -S . -B build -DREFLECTCPP_BUILD_TESTS=ON -DREFLECTCPP_FLEXBUFFERS=ON -DREFLECTCPP_XML=ON -DREFLECTCPP_YAML=ON -DCMAKE_BUILD_TYPE=Release
499+
cmake -S . -B build -DREFLECTCPP_BUILD_TESTS=ON -DREFLECTCPP_BSON=ON -DREFLECTCPP_FLEXBUFFERS=ON -DREFLECTCPP_XML=ON -DREFLECTCPP_YAML=ON -DCMAKE_BUILD_TYPE=Release
498500
cmake --build build -j 4 # gcc, clang
499501
cmake --build build --config Release -j 4 # MSVC
500502
```

Diff for: docs/README.md

+5-3
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,13 @@
5656

5757
5.1) [JSON](https://github.com/getml/reflect-cpp/blob/main/docs/json.md)
5858

59-
5.2) [flexbuffers](https://github.com/getml/reflect-cpp/blob/main/docs/flexbuffers.md)
59+
5.2) [BSON](https://github.com/getml/reflect-cpp/blob/main/docs/bson.md)
6060

61-
5.3) [XML](https://github.com/getml/reflect-cpp/blob/main/docs/xml.md)
61+
5.3) [flexbuffers](https://github.com/getml/reflect-cpp/blob/main/docs/flexbuffers.md)
6262

63-
5.4) [YAML](https://github.com/getml/reflect-cpp/blob/main/docs/yaml.md)
63+
5.4) [XML](https://github.com/getml/reflect-cpp/blob/main/docs/xml.md)
64+
65+
5.5) [YAML](https://github.com/getml/reflect-cpp/blob/main/docs/yaml.md)
6466

6567
## 6) Advanced topics
6668

Diff for: docs/bson.md

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# BSON
2+
3+
For BSON support, you must also include the header `<rfl/bson.hpp>` and link to the libbson library (https://github.com/mongodb/libbson).
4+
5+
Like the name implies, BSON is a JSON-like binary format. It is most notably used by MongoDB.
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 turned into a bytes vector like this:
21+
22+
```cpp
23+
const auto person = Person{...};
24+
const auto bytes = rfl::bson::write(person);
25+
```
26+
27+
You can parse bytes like this:
28+
29+
```cpp
30+
const rfl::Result<Person> result = rfl::bson::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::bson::load<Person>("/path/to/file.bson");
39+
40+
const auto person = Person{...};
41+
rfl::bson::save("/path/to/file.bson", 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::bson::read<Person>(my_istream);
50+
51+
const auto person = Person{...};
52+
rfl::bson::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::bson::write(person, std::cout) << std::endl;
59+
```
60+
61+
(Since BSON 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 BSON format, these must be a static function on your struct or class called
72+
`from_bson` that take a `rfl::bson::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::bson::Reader::InputVarType;
84+
static rfl::Result<Person> from_bson(const InputVarType& _obj);
85+
};
86+
```
87+
88+
And in your source file, you implement `from_bson` as follows:
89+
90+
```cpp
91+
rfl::Result<Person> Person::from_bson(const InputVarType& _obj) {
92+
const auto from_nt = [](auto&& _nt) {
93+
return rfl::from_named_tuple<Person>(std::move(_nt));
94+
};
95+
return rfl::bson::read<rfl::named_tuple_t<Person>>(_obj)
96+
.transform(from_nt);
97+
}
98+
```
99+
100+
This will force the compiler to only compile the BSON parsing when the source file is compiled.

Diff for: include/rfl/bson.hpp

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#ifndef RFL_BSON_HPP_
2+
#define RFL_BSON_HPP_
3+
4+
#include "bson/Parser.hpp"
5+
#include "bson/Reader.hpp"
6+
#include "bson/Writer.hpp"
7+
#include "bson/load.hpp"
8+
#include "bson/read.hpp"
9+
#include "bson/save.hpp"
10+
#include "bson/write.hpp"
11+
12+
#endif

Diff for: include/rfl/bson/Parser.hpp

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#ifndef RFL_BSON_PARSER_HPP_
2+
#define RFL_BSON_PARSER_HPP_
3+
4+
#include "../parsing/Parser.hpp"
5+
#include "Reader.hpp"
6+
#include "Writer.hpp"
7+
8+
namespace rfl {
9+
namespace bson {
10+
11+
template <class T>
12+
using Parser = parsing::Parser<Reader, Writer, T>;
13+
14+
}
15+
} // namespace rfl
16+
17+
#endif

0 commit comments

Comments
 (0)