Home

Awesome

puffer Protocol Puffers

Codacy Github Actions Vcpkg Port Conan Center Codecov

A little, highly templated, and protobuf-compatible serialization/deserialization library written in C++20

:closed_book: Documentation

Requirements

Features

An Example

For the following data structure described using .proto:

message Student {
    uint32 id = 1;
    string name = 3;
}

message Class {
    string name = 8;
    repeated Student students = 3;
}

We can use protopuf to describe it as C++ types:

using namespace pp;

using Student = message<
    uint32_field<"id", 1>,
    string_field<"name", 3>
>;

using Class = message<
    string_field<"name", 8>,
    message_field<"students", 3, Student, repeated>
>;

Subsequently, both serialization and deserialization become so easy to do:

// serialization
Student twice {123, "twice"}, tom{456, "tom"}, jerry{123456, "jerry"};
Class myClass {"class 101", {tom, jerry}};
myClass["students"_f].push_back(twice);

array<byte, 64> buffer{};
auto result = message_coder<Class>::encode(myClass, buffer);
assert(result.has_value());
const auto& bufferEnd = *result;
assert(begin_diff(bufferEnd, buffer) == 45);

// deserialization
auto result2 = message_coder<Class>::decode(buffer);
assert(result2.has_value());
const auto& [yourClass, bufferEnd2] = *result2;
assert(yourClass["name"_f] == "class 101");
assert(yourClass["students"_f][2]["name"_f] == "twice");
assert(yourClass["students"_f][2]["id"_f] == 123);
assert(yourClass["students"_f][1] == (Student{123456, "jerry"}));
assert(yourClass == myClass);
assert(begin_diff(bufferEnd2, bufferEnd) == 0);

More examples can be found in our test cases (test/message.cpp).

Supported Field Types

CategorySupported Types
Varintint32, int64, uint32, uint64, sint32, sint64, bool, enum
64-bitfixed64, sfixed64, double
Length-delimitedstring, bytes, embedded messages, packed repeated fields
32-bitfixed32, sfixed32, float

Known issues

Acknowledgement