Skip to content

Commit

Permalink
Renamed project
Browse files Browse the repository at this point in the history
"cereal-pack" is to similar to "cereal"
  • Loading branch information
crabmandable committed Jun 25, 2022
1 parent 06d2944 commit 19f47bc
Show file tree
Hide file tree
Showing 40 changed files with 372 additions and 372 deletions.
52 changes: 26 additions & 26 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.6)

project(CerealPack CXX)
project(CruncyBytes CXX)

if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 17)
Expand All @@ -9,55 +9,55 @@ endif()

find_package(Python3 COMPONENTS Interpreter REQUIRED)
if(NOT ${Python3_FOUND})
message(FATAL_ERROR "Python3 is required to generate the cereal_pack classes")
message(FATAL_ERROR "Python3 is required to generate the crunchy_bytes classes")
endif()

if (NOT DEFINED CEREAL_PACK_SCHEMA_DIR AND NOT DEFINED CEREAL_PACK_SCHEMA_FILES)
if (NOT DEFINED CRUNCHY_BYTES_SCHEMA_DIR AND NOT DEFINED CRUNCHY_BYTES_SCHEMA_FILES)
message(FATAL_ERROR
"A schema directory or schema files should be defined using the CMake variables CEREAL_PACK_SCHEMA_DIR or CEREAL_PACK_SCHEMA_FILES")
elseif(DEFINED CEREAL_PACK_SCHEMA_DIR)
set(CEREAL_PACK_SCHEMA_FILES "")
file(GLOB_RECURSE CEREAL_PACK_SCHEMA_FILES "${CEREAL_PACK_SCHEMA_DIR}/*.toml")
"A schema directory or schema files should be defined using the CMake variables CRUNCHY_BYTES_SCHEMA_DIR or CRUNCHY_BYTES_SCHEMA_FILES")
elseif(DEFINED CRUNCHY_BYTES_SCHEMA_DIR)
set(CRUNCHY_BYTES_SCHEMA_FILES "")
file(GLOB_RECURSE CRUNCHY_BYTES_SCHEMA_FILES "${CRUNCHY_BYTES_SCHEMA_DIR}/*.toml")
endif()

if (NOT DEFINED CEREAL_PACK_OUTPUT_DIR)
if (NOT DEFINED CRUNCHY_BYTES_OUTPUT_DIR)
message(FATAL_ERROR
"An output directory for generated cereal_pack classes must be set using the CMake variable CEREAL_PACK_OUTPUT_DIR")
"An output directory for generated crunchy_bytes classes must be set using the CMake variable CRUNCHY_BYTES_OUTPUT_DIR")
endif()

if (DEFINED CEREAL_PACK_GLOBALS)
set(CEREAL_PACK_GLOBALS_OPT "-g" "${CEREAL_PACK_GLOBALS}")
if (DEFINED CRUNCHY_BYTES_GLOBALS)
set(CRUNCHY_BYTES_GLOBALS_OPT "-g" "${CRUNCHY_BYTES_GLOBALS}")
endif()

set(CEREAL_PACK_GENERATE_COMMAND
set(CRUNCHY_BYTES_GENERATE_COMMAND
"${Python3_EXECUTABLE}"
"${CMAKE_CURRENT_SOURCE_DIR}/cereal_pack.py"
"-o" "${CEREAL_PACK_OUTPUT_DIR}"
"-s" "${CEREAL_PACK_SCHEMA_FILES}"
"${CEREAL_PACK_GLOBALS_OPT}"
"${CMAKE_CURRENT_SOURCE_DIR}/crunchy_bytes.py"
"-o" "${CRUNCHY_BYTES_OUTPUT_DIR}"
"-s" "${CRUNCHY_BYTES_SCHEMA_FILES}"
"${CRUNCHY_BYTES_GLOBALS_OPT}"
)

execute_process(
COMMAND ${CEREAL_PACK_GENERATE_COMMAND} --cmake
COMMAND ${CRUNCHY_BYTES_GENERATE_COMMAND} --cmake
OUTPUT_VARIABLE GENERATED_FILES
RESULT_VARIABLE RETURN_VALUE
)

if (NOT RETURN_VALUE EQUAL 0)
message(FATAL_ERROR "Failed to generate source list from cereal_pack schemas. See above")
message(FATAL_ERROR "Failed to generate source list from crunchy_bytes schemas. See above")
endif()

set(CEREAL_PACK_GENERATOR_CODE "")
file(GLOB_RECURSE CEREAL_PACK_GENERATOR_CODE
"${CMAKE_CURRENT_SOURCE_DIR}/cereal_pack.py"
set(CRUNCHY_BYTES_GENERATOR_CODE "")
file(GLOB_RECURSE CRUNCHY_BYTES_GENERATOR_CODE
"${CMAKE_CURRENT_SOURCE_DIR}/crunchy_bytes.py"
"${CMAKE_CURRENT_SOURCE_DIR}/generator/*.py")

add_custom_command(
COMMAND ${CEREAL_PACK_GENERATE_COMMAND}
DEPENDS ${CEREAL_PACK_GENERATOR_CODE} ${CEREAL_PACK_SCHEMA_FILES} ${CEREAL_PACK_GLOBALS}
COMMAND ${CRUNCHY_BYTES_GENERATE_COMMAND}
DEPENDS ${CRUNCHY_BYTES_GENERATOR_CODE} ${CRUNCHY_BYTES_SCHEMA_FILES} ${CRUNCHY_BYTES_GLOBALS}
OUTPUT ${GENERATED_FILES}
COMMENT "Generating cereal_pack classes"
COMMENT "Generating crunchy_bytes classes"
)

add_library(cereal_pack_interface INTERFACE ${GENERATED_FILES})
target_include_directories(cereal_pack_interface INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/includes" "${CEREAL_PACK_OUTPUT_DIR}")
add_library(crunchy_bytes_interface INTERFACE ${GENERATED_FILES})
target_include_directories(crunchy_bytes_interface INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/includes" "${CRUNCHY_BYTES_OUTPUT_DIR}")
88 changes: 44 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
# Cereal Pack 🥣
# Crunchy Bytes 🥣

#### C++ Schema Serialization Library

![cereal-gif](./cereal_pack.gif)
![crunchy-gif](./crunchy_bytes.gif)

## What is Cereal Pack?
## What is Crunchy Bytes?

`cereal_pack` is a C++ 17 library that serializes structured data.
`crunchy_bytes` is a C++ 17 library that serializes structured data.

You bring the data definitions, and `cereal_pack` will generate C++ classes that can
You bring the data definitions, and `crunchy_bytes` will generate C++ classes that can
`serialize` and `deserialize` themselves into a compact binary representation that
can be easily be transferred between processes.

`cereal_pack` is ideal for IPC, or long term data storage
`crunchy_bytes` is ideal for IPC, or long term data storage

## Getting Started
### Requirements
Expand All @@ -25,7 +25,7 @@ pip install toml
Schemas are defined by creating [TOML](https://toml.io/en/) documents.

Each provided `.toml` file will be converted into a C++ class that inherits from
`cereal_pack::Schema`.
`crunchy_bytes::Schema`.

The only required top level properties of a TOML schema are it's `name` and its
`props`.
Expand All @@ -48,51 +48,51 @@ Once you have your schemas the process to generate your C++ classes is pretty
simple

#### Using CMake:
Add `cereal_pack` to your `CMakeLists.txt` as a `subdirectory`
Add `crunchy_bytes` to your `CMakeLists.txt` as a `subdirectory`
and tell it where to find your `.toml` schemas, and where to place the generated
classes
```cmake
# Either set `CEREAL_PACK_SCHEMA_FILES` explicitly
set(CEREAL_PACK_SCHEMA_FILES
# Either set `CRUNCHY_BYTES_SCHEMA_FILES` explicitly
set(CRUNCHY_BYTES_SCHEMA_FILES
"./my_schemas/schema_one.toml"
"./my_schemas/schema_two.toml"
)
# OR set `CEREAL_PACK_SCHEMA_DIR` which will recursively search the directory for .toml files
set(CEREAL_PACK_SCHEMA_DIR "./my-schemas")
# OR set `CRUNCHY_BYTES_SCHEMA_DIR` which will recursively search the directory for .toml files
set(CRUNCHY_BYTES_SCHEMA_DIR "./my-schemas")
# This will place the generated files in our build directory
set(CEREAL_PACK_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/my-schemas")
set(CRUNCHY_BYTES_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/my-schemas")
# add the `cereal_pack` subdirectory
add_subdirectory(${PATH_TO_CEREAL_PACK} cereal_pack_interface)
# add the `crunchy_bytes` subdirectory
add_subdirectory(${PATH_TO_CRUNCHY_BYTES} crunchy_bytes_interface)
```
Then simply link `cereal_pack_interface` into your program
Then simply link `crunchy_bytes_interface` into your program
```cmake
target_link_libraries(my_program cereal_pack_interface)
target_link_libraries(my_program crunchy_bytes_interface)
```

The advantage of using cereal_pack's `CMakeLists.txt` is that any change to `cereal_pack`
The advantage of using crunchy_bytes's `CMakeLists.txt` is that any change to `crunchy_bytes`
or to your schemas will cause the generated C++ classes to be regenerated

[Check out the test suite CMakeLists.txt for another example](./test/CMakeLists.txt)

#### Manually:
First you need to use `cereal_pack.py` to generate the C++ classes
First you need to use `crunchy_bytes.py` to generate the C++ classes
```sh
python cereal_pack.py -s ./my-schemas/* -o generated-classes/
python crunchy_bytes.py -s ./my-schemas/* -o generated-classes/
```

Then simply include `cereal_pack` and the `generated-classes` in your build
Then simply include `crunchy_bytes` and the `generated-classes` in your build
```sh
g++ main.cpp -I./cereal_pack -I./generated-classes -o my_program
g++ main.cpp -I./crunchy_bytes -I./generated-classes -o my_program
```

## Usage
### Generated C++ Schemas
The generated C++ schemas are more or less containers for lists of properties.
Each property on the class translates into a getter method which will return a
subclass of `cereal_pack::Property`.
subclass of `crunchy_bytes::Property`.

For example, the schema generated by this TOML file
```toml
Expand All @@ -105,9 +105,9 @@ name = "Cereal"
type = "string"
max_length = 32
```
Will have an `is_cereal` method that returns a `cereal_pack::Primitive<bool>`
Will have an `is_cereal` method that returns a `crunchy_bytes::Primitive<bool>`

All `cereal_pack::Property` classes are simple wrappers that allow you to `get`
All `crunchy_bytes::Property` classes are simple wrappers that allow you to `get`
or `set` the property.

Putting it all together:
Expand Down Expand Up @@ -137,7 +137,7 @@ assert(s.set_of_things()[0] == a_thing);
```
#### Nested schemas
The only property getter that won't return a `cereal_pack::Property` is the `reference`
The only property getter that won't return a `crunchy_bytes::Property` is the `reference`
type.
When using the `reference` property type to nest schemas, the generated getter
Expand Down Expand Up @@ -176,12 +176,12 @@ box.brand().set("Kollogs Quran Flakes");
// And if you want to set all the dimensions at once you can use the `=` operator
CerealBox same_size_box;
same_size_box.box_dimensions() = box.box_dimensions();
same_size_box.brand().set("Commander Crunch");
same_size_box.brand().set("Crunchy Bytes");
```

#### Serialization
You probably don't need it explained to you that you can `serialize` and `deserialize`
`cereal_pack` schemas.
`crunchy_bytes` schemas.
```C++
CerealBox box;
// TODO: set some of the properties
Expand All @@ -193,7 +193,7 @@ uint32_t length_read = another_box.deserialize(buffer);

#### Constants

All `cereal_pack` schema classes contain a `constants` "namespace" [^1]
All `crunchy_bytes` schema classes contain a `constants` "namespace" [^1]

[^1]: Actually C++ doesn't support namespaces inside a class, but a `struct` with
the constructor deleted does the trick
Expand Down Expand Up @@ -260,10 +260,10 @@ for (auto& barcode: stock.barcodes().get()) {
}
```
### Globals
The generated code will _always_ include a file called `cereal_pack_globals.hpp`.
The generated code will _always_ include a file called `crunchy_bytes_globals.hpp`.
This will include the namespace `cereal_pack::globals`, containing constants &
definitions. By default the only thing in here will be `max_cereal_pack_serial_length`,
This will include the namespace `crunchy_bytes::globals`, containing constants &
definitions. By default the only thing in here will be `max_crunchy_bytes_serial_length`,
but you can add to this by supplying a global definitions file.
Globals can also be used to avoid repeating constant & enum definitions in multiple
Expand All @@ -272,10 +272,10 @@ schema files.
[More detail on globals can be found here](./docs/GLOBALS.md)
### Router
`cereal_pack` provides a router class that can be used to work with messages
created with `cereal_pack`. It is small and simple to use
`crunchy_bytes` provides a router class that can be used to work with messages
created with `crunchy_bytes`. It is small and simple to use
```C++
using namespace cereal_pack::router;
using namespace crunchy_bytes::router;
BasicRouter<MyCustomHeader> r([] (const MyCustomHeader& h) { return h.body_name().get(); });
r.attatch_route<ImportantEvent>([](const ImportantEvent& event) {
Expand All @@ -287,12 +287,12 @@ r.attatch_route<UrgentEvent>([](const UrgentEvent& event) {
});
while (true) {
std::vector<uint8_t> cereal_data = read_ipc();
r.handle_message(cereal_data.data());
std::vector<uint8_t> crunchy_data = read_ipc();
r.handle_message(crunchy_data.data());
}
```
It's up to you to define how you want your message headers to look,
you just need to tell `cereal_pack` how to read your header.
you just need to tell `crunchy_bytes` how to read your header.

[More detail on routers can be found here](./docs/ROUTER.md)

Expand All @@ -301,13 +301,13 @@ you just need to tell `cereal_pack` how to read your header.
They probably wouldn't! :)

Seriously, [ProtoBuf](https://developers.google.com/protocol-buffers) is a very mature, and well tested library with many more features, and it's developed by freaking _Google_.
`cereal_pack` is a hobby project made by one dude. There is no way it can compete
`crunchy_bytes` is a hobby project made by one dude. There is no way it can compete
in terms of features, or stability.

However, if you need something _small & simple_, for C++ _only_, then maybe `cereal_pack`
can work for you. Due to a slightly simpler design `cereal_pack` has a handful of advantages
However, if you need something _small & simple_, for C++ _only_, then maybe `crunchy_bytes`
can work for you. Due to a slightly simpler design `crunchy_bytes` has a handful of advantages

#### It's tiny & embedded friendly
#### It's tiny
* The core library that supports the generated C++ classes is _very_ small

* It's header only, including the generated classes
Expand All @@ -317,13 +317,13 @@ can work for you. Due to a slightly simpler design `cereal_pack` has a handful o
* There is no "compiler", just some python scripts that generate the C++ classes

#### Max sizes
Every `cereal_pack` schema has a _maximum_ size when serialized. Having a determinate
Every `crunchy_bytes` schema has a _maximum_ size when serialized. Having a determinate
amount of memory required makes code safer & simpler.

And the generated code can always tell you how much space you need to buffer any
of your schemas
```C++
std::array<uint8_t, cereal_pack::globals::max_cereal_pack_serial_length> msgBuffer;
std::array<uint8_t, crunchy_bytes::globals::max_crunchy_bytes_serial_length> msgBuffer;
```

This can make message handling logic very simple, as you can ensure each packet
Expand Down
Binary file removed cereal_pack.gif
Binary file not shown.
Binary file added crunchy_bytes.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions cereal_pack.py → crunchy_bytes.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def path_of_class(root, schema):
return pathlib.Path(root, *schema.name_with_namespace.split('::')[:-1], schema.name + '.hpp')

if __name__ == '__main__':
arg_parser = argparse.ArgumentParser(description='Generate cereal pack c++ classes from a list of schemas.')
arg_parser = argparse.ArgumentParser(description='Generate crunchy bytes c++ classes from a list of schemas.')

arg_parser.add_argument('--schemas', '-s', metavar='schema', nargs='+', required=True,
help='schema files to genearte classes from')
Expand All @@ -32,7 +32,7 @@ def path_of_class(root, schema):

pathlib.Path(args.out_dir).mkdir(exist_ok=True)

with open(pathlib.Path(args.out_dir, 'cereal_pack_globals.hpp'), 'w') as file:
with open(pathlib.Path(args.out_dir, 'crunchy_bytes_globals.hpp'), 'w') as file:
file.write(generate.globals_header(globals, schemas))

for s in schemas.values():
Expand Down
22 changes: 11 additions & 11 deletions docs/GLOBALS.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
### Globals
The generated code will _always_ include a file called `cereal_pack_globals.hpp`.
The generated code will _always_ include a file called `crunchy_byte_globals.hpp`.

This will include the namespace `cereal_pack::globals`, containing constants &
definitions. By default the only thing in here will be `max_cereal_pack_serial_length`,
This will include the namespace `crunchy_bytes::globals`, containing constants &
definitions. By default the only thing in here will be `max_crunchy_bytes_serial_length`,
but you can add to this by supplying a global definitions file.

Globals can also be used to avoid repeating constant & enum definitions in multiple
Expand All @@ -16,25 +16,25 @@ order to facilitate this you can supply a file with global definitions
that can be referenced in your schemas.

##### Using CMake
You can define a globals file to use by setting the cmake variable `CEREAL_PACK_GLOBALS`
You can define a globals file to use by setting the cmake variable `CRUNCHY_BYTE_GLOBALS`
```cmake
set(CEREAL_PACK_GLOBALS "${CMAKE_CURRENT_SOURCE_DIR}/cereal_pack_globals.toml")
set(CRUNCHY_BYTE_GLOBALS "${CMAKE_CURRENT_SOURCE_DIR}/crunchy_byte_globals.toml")
```

##### Manually
The globals file can be passed to `cereal_pack.py` with the `--globals` or `-g` option
The globals file can be passed to `crunchy_bytes.py` with the `--globals` or `-g` option
```sh
python cereal_pack.py -g ./my_globals.toml -s ./my-schemas/* -o generated-classes/
python crunchy_bytes.py -g ./my_globals.toml -s ./my-schemas/* -o generated-classes/
```

The file can contain the keys:
* `max_cereal_pack_serial_length`
* `max_crunchy_bytes_serial_length`

This is a `uint32_t` that will be directly added to the `cereal_pack::globals`
This is a `uint32_t` that will be directly added to the `crunchy_bytes::globals`
namespace, and will will enforce that _no_ schema ever exceeds this length
when serialized (an error will be thrown during code generation).

If you do not supply this feild, it will still appear in the `cereal_pack::gloabls`
If you do not supply this feild, it will still appear in the `crunchy_bytes::gloabls`
namespace, with the maximum length that any of your schemas can be when serialized.

* `lengths`
Expand All @@ -49,7 +49,7 @@ The file can contain the keys:

E.g.
```toml
max_cereal_pack_serial_length = 8192
max_crunchy_bytes_serial_length = 8192

[lengths]
max_number_of_marshmallows = 100
Expand Down
Loading

0 comments on commit 19f47bc

Please sign in to comment.