Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
schema_impl.hpp
Go to the documentation of this file.
1#pragma once
2
5#include "concepts.hpp"
6#include "schema_name.hpp"
7
8#include <array>
9#include <concepts>
10#include <map>
11#include <memory>
12#include <optional>
13#include <set>
14#include <sstream>
15#include <string>
16#include <tuple>
17#include <variant>
18#include <vector>
19
21
22template <typename T> inline void _msgpack_schema_pack(MsgpackSchemaPacker& packer, const T& obj);
23
24struct MsgpackSchemaPacker : msgpack::packer<msgpack::sbuffer> {
25 MsgpackSchemaPacker(msgpack::sbuffer& stream)
26 : packer<msgpack::sbuffer>(stream)
27 {}
28
29 std::set<std::string> emitted_types;
30
31 bool set_emitted(const std::string& type)
32 {
33 if (emitted_types.find(type) == emitted_types.end()) {
34 emitted_types.insert(type);
35 return false;
36 }
37 return true;
38 }
39
40 void pack_alias(const std::string& schema_name, const std::string& msgpack_name)
41 {
42 pack_array(2);
43 pack("alias");
44 pack_array(2);
45 pack(schema_name);
46 pack(msgpack_name);
47 }
48
49 template <typename T> void pack_schema(const T& obj) { _msgpack_schema_pack(*this, obj); }
50
51 template <typename... Args> void pack_template_type(const std::string& schema_name)
52 {
53 pack_array(2);
54 pack(schema_name);
55 pack_array(sizeof...(Args));
57 }
58
59 template <msgpack_concepts::HasMsgPack T> void pack_with_name(const std::string& type, T const& object)
60 {
61 if (set_emitted(type)) {
62 pack(type);
63 return;
64 }
66 const_cast<T&>(object).msgpack([&](auto&... args) {
67 size_t kv_size = sizeof...(args);
68 pack_map(uint32_t(1 + kv_size / 2));
69 pack("__typename");
70 pack(type);
71 _schema_pack_map_content(*this, args...);
72 });
73 }
74};
75
77
78namespace msgpack_concepts {
79template <typename T>
80concept SchemaPackable = requires(T value, MsgpackSchemaPacker packer) { msgpack_schema_pack(packer, value); };
81
82template <typename T>
83concept IpcBin32Alias = requires {
84 typename T::IPC_CODEGEN_BIN32_ALIAS;
85 T::MSGPACK_SCHEMA_NAME;
86};
87} // namespace msgpack_concepts
88
89template <typename Value, typename... Rest>
91 std::string key,
92 const Value& value,
93 const Rest&... rest)
94{
95 static_assert(
97 "see the first type argument in the error trace, it might require a specialization of msgpack_schema_pack");
98 packer.pack(key);
100 _schema_pack_map_content(packer, rest...);
101}
102
103template <msgpack_concepts::IpcBin32Alias T> inline void msgpack_schema_pack(MsgpackSchemaPacker& packer, T const&)
104{
105 packer.pack_alias(T::MSGPACK_SCHEMA_NAME, "bin32");
106}
107
108template <typename T>
111inline void msgpack_schema_pack(MsgpackSchemaPacker& packer, T const& obj)
112{
113 packer.pack(msgpack_schema_name(obj));
114}
115
116template <msgpack_concepts::HasMsgPackSchema T>
117inline void msgpack_schema_pack(MsgpackSchemaPacker& packer, T const& obj)
118{
119 obj.msgpack_schema(packer);
120}
121
122template <msgpack_concepts::HasMsgPack T>
124inline void msgpack_schema_pack(MsgpackSchemaPacker& packer, T const& object)
125{
126 std::string type = msgpack_schema_name(object);
127 packer.pack_with_name(type, object);
128}
129
130template <typename T> inline void _msgpack_schema_pack(MsgpackSchemaPacker& packer, const T& obj)
131{
133 "see the first type argument in the error trace, it might need a msgpack_schema method!");
134 msgpack_schema_pack(packer, obj);
135}
136
137template <typename... Args> inline void msgpack_schema_pack(MsgpackSchemaPacker& packer, std::tuple<Args...> const&)
138{
139 packer.pack_template_type<Args...>("tuple");
140}
141
142template <typename K, typename V> inline void msgpack_schema_pack(MsgpackSchemaPacker& packer, std::map<K, V> const&)
143{
144 packer.pack_template_type<K, V>("map");
145}
146
147template <typename T> inline void msgpack_schema_pack(MsgpackSchemaPacker& packer, std::optional<T> const&)
148{
149 packer.pack_template_type<T>("optional");
150}
151
152template <typename T> inline void msgpack_schema_pack(MsgpackSchemaPacker& packer, std::vector<T> const&)
153{
154 packer.pack_template_type<T>("vector");
155}
156
157template <typename... Args> inline void msgpack_schema_pack(MsgpackSchemaPacker& packer, std::variant<Args...> const&)
158{
159 packer.pack_template_type<Args...>("variant");
160}
161
162template <typename T> inline void msgpack_schema_pack(MsgpackSchemaPacker& packer, std::shared_ptr<T> const&)
163{
164 packer.pack_template_type<T>("shared_ptr");
165}
166
167template <typename T, std::size_t N>
169{
170 packer.pack_array(2);
171 packer.pack("array");
172 packer.pack_array(2);
174 packer.pack(N);
175}
176
177inline std::string msgpack_schema_to_string(const auto& obj)
178{
179 msgpack::sbuffer output;
180 MsgpackSchemaPacker printer{ output };
181 _msgpack_schema_pack(printer, obj);
182 msgpack::object_handle oh = msgpack::unpack(output.data(), output.size());
183 std::stringstream pretty_output;
184 pretty_output << oh.get() << std::endl;
185 return pretty_output.str();
186}
void check_msgpack_usage(const auto &object)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
void _msgpack_schema_pack(MsgpackSchemaPacker &packer, const T &obj)
void _schema_pack_map_content(MsgpackSchemaPacker &)
void msgpack_schema_pack(MsgpackSchemaPacker &packer, T const &)
std::string msgpack_schema_to_string(const auto &obj)
std::string msgpack_schema_name(T const &)
void pack_alias(const std::string &schema_name, const std::string &msgpack_name)
bool set_emitted(const std::string &type)
void pack_with_name(const std::string &type, T const &object)
MsgpackSchemaPacker(msgpack::sbuffer &stream)
std::set< std::string > emitted_types
void pack_template_type(const std::string &schema_name)
void pack_schema(const T &obj)