Nix 2.93.3
Lix: A modern, delicious implementation of the Nix package manager; unstable internal interfaces
Loading...
Searching...
No Matches
length-prefixed-protocol-helper.hh
1#pragma once
8
11
12namespace nix {
13
14class Store;
15
29template<class Inner, typename T>
31
44
45#define LENGTH_PREFIXED_PROTO_HELPER(Inner, T) \
46 struct LengthPrefixedProtoHelper< Inner, T > \
47 { \
48 static T read(const Store & store, typename Inner::ReadConn conn); \
49 [[nodiscard]] static WireFormatGenerator write(const Store & store, typename Inner::WriteConn conn, const T & str); \
50 private: \
51 template<typename U> using S = typename Inner::template Serialise<U>; \
52 }
53
54template<class Inner, typename T>
55LENGTH_PREFIXED_PROTO_HELPER(Inner, std::vector<T>);
56
57template<class Inner, typename T>
58LENGTH_PREFIXED_PROTO_HELPER(Inner, std::set<T>);
59
60template<class Inner, typename... Ts>
61LENGTH_PREFIXED_PROTO_HELPER(Inner, std::tuple<Ts...>);
62
63template<class Inner, typename K, typename V>
64#define DONT_SUBSTITUTE_KV_TYPE std::map<K, V>
65LENGTH_PREFIXED_PROTO_HELPER(Inner, DONT_SUBSTITUTE_KV_TYPE);
66#undef DONT_SUBSTITUTE_KV_TYPE
67
68template<class Inner, typename T>
69std::vector<T>
71 const Store & store, typename Inner::ReadConn conn)
72{
73 std::vector<T> resSet;
74 auto size = readNum<size_t>(conn.from);
75 while (size--) {
76 resSet.push_back(S<T>::read(store, conn));
77 }
78 return resSet;
79}
80
81template<class Inner, typename T>
82WireFormatGenerator
83LengthPrefixedProtoHelper<Inner, std::vector<T>>::write(
84 const Store & store, typename Inner::WriteConn conn, const std::vector<T> & resSet)
85{
86 co_yield resSet.size();
87 for (auto & key : resSet) {
88 co_yield S<T>::write(store, conn, key);
89 }
90}
91
92template<class Inner, typename T>
93std::set<T>
95 const Store & store, typename Inner::ReadConn conn)
96{
97 std::set<T> resSet;
98 auto size = readNum<size_t>(conn.from);
99 while (size--) {
100 resSet.insert(S<T>::read(store, conn));
101 }
102 return resSet;
103}
104
105template<class Inner, typename T>
106WireFormatGenerator
108 const Store & store, typename Inner::WriteConn conn, const std::set<T> & resSet)
109{
110 co_yield resSet.size();
111 for (auto & key : resSet) {
112 co_yield S<T>::write(store, conn, key);
113 }
114}
115
116template<class Inner, typename K, typename V>
117std::map<K, V>
119 const Store & store, typename Inner::ReadConn conn)
120{
121 std::map<K, V> resMap;
122 auto size = readNum<size_t>(conn.from);
123 while (size--) {
124 auto k = S<K>::read(store, conn);
125 auto v = S<V>::read(store, conn);
126 resMap.insert_or_assign(std::move(k), std::move(v));
127 }
128 return resMap;
129}
130
131template<class Inner, typename K, typename V>
132WireFormatGenerator
134 const Store & store, typename Inner::WriteConn conn, const std::map<K, V> & resMap)
135{
136 co_yield resMap.size();
137 for (auto & i : resMap) {
138 co_yield S<K>::write(store, conn, i.first);
139 co_yield S<V>::write(store, conn, i.second);
140 }
141}
142
143template<class Inner, typename... Ts>
144std::tuple<Ts...>
145LengthPrefixedProtoHelper<Inner, std::tuple<Ts...>>::read(
146 const Store & store, typename Inner::ReadConn conn)
147{
148 return std::tuple<Ts...> {
149 S<Ts>::read(store, conn)...,
150 };
151}
152
153template<class Inner, typename... Ts>
154WireFormatGenerator
155LengthPrefixedProtoHelper<Inner, std::tuple<Ts...>>::write(
156 const Store & store, typename Inner::WriteConn conn, const std::tuple<Ts...> & res)
157{
158 auto fullArgs = std::apply(
159 [&](auto &... rest) {
160 return std::tuple<const Store &, typename Inner::WriteConn &, const Ts &...>(
161 std::cref(store), conn, rest...
162 );
163 },
164 res
165 );
166 return std::apply(
167 []<typename... Us>(auto & store, auto conn, const Us &... args) -> WireFormatGenerator {
168 (co_yield S<Us>::write(store, conn, args), ...);
169 },
170 fullArgs
171 );
172}
173
174}
Definition store-api.hh:195
Definition length-prefixed-protocol-helper.hh:30