12#include <spdlog/spdlog.h>
84 std::vector<std::unique_ptr<RouteArgDef>>
children;
110 const std::string &
getData()
const;
124 const std::vector<std::unique_ptr<RouteArgDef>> &
getChildren()
const;
135 constexpr static const char ARRAY_START_IDENTIFIER =
'[';
136 constexpr static const char ARRAY_END_IDENTIFIER =
']';
138 constexpr static const unsigned int MAX_OBJECT_FIELDS = 5;
139 constexpr static const char OBJECT_START_IDENTIFIER =
'(';
140 constexpr static const char OBJECT_END_IDENTIFIER =
')';
141 constexpr static const char OBJECT_FIELDS_DELIMETER =
';';
146 typename T::value_type;
147 typename T::iterator;
154 std::is_array<T>::value ||
155 std::is_same_v<T, std::vector<typename T::value_type>> ||
156 std::is_same_v<T, std::list<typename T::value_type>>
160 struct is_tuple_like_impl : std::false_type {};
162 template<
typename... Ts>
163 struct is_tuple_like_impl<std::tuple<Ts...>> : std::true_type {};
165 template<
typename T1,
typename T2>
166 struct is_tuple_like_impl<std::pair<T1, T2>> : std::true_type {};
170 is_tuple_like_impl<std::remove_cv_t<std::remove_reference_t<T>>>::value
171 && std::tuple_size<T>::value > 0
172 && std::tuple_size<T>::value < MAX_OBJECT_FIELDS;
193 parse::Result<server::RouteArgDef> parseRouteArgDefFromString(
const std::string str);
197 parse::Result<T> parseRouteArgAs(
const server::RouteArg & arg);
207 parse::Result<std::size_t> parseRouteArgAs<std::size_t>(
const server::RouteArg & arg);
217 parse::Result<std::uint32_t> parseRouteArgAs<std::uint32_t>(
const server::RouteArg & arg);
227 parse::Result<std::string> parseRouteArgAs<std::string>(
const server::RouteArg & arg);
230 template <IsTupleLike TupleT, std::
size_t Size>
233 template <IsTupleLike TupleT>
234 struct TupleParser<TupleT, 2>
236 parse::Result<TupleT> operator()(
const std::vector<std::unique_ptr<dcn::server::RouteArgDef>> &defs,
const std::vector<std::string> & values_str)
241 auto t0 = parseRouteArgAs<typename std::tuple_element<0, TupleT>::type>(
server::RouteArg(*defs.at(0), values_str.at(0)));
242 if(!t0)
return std::unexpected(t0.error());
244 auto t1 = parseRouteArgAs<typename std::tuple_element<0, TupleT>::type>(
server::RouteArg(*defs.at(1), values_str.at(1)));
245 if(!t1)
return std::unexpected(t1.error());
247 return std::make_tuple(*t0, *t1);
251 template <IsTupleLike TupleT>
252 struct TupleParser<TupleT, 3>
254 parse::Result<TupleT> operator()(
const std::vector<std::unique_ptr<dcn::server::RouteArgDef>> &defs,
const std::vector<std::string> & values_str)
259 auto t0 = parseRouteArgAs<typename std::tuple_element<0, TupleT>::type>(server::RouteArg(*defs.at(0), values_str.at(0)));
260 if(!t0)
return std::unexpected(t0.error());
262 auto t1 = parseRouteArgAs<typename std::tuple_element<0, TupleT>::type>(server::RouteArg(*defs.at(1), values_str.at(1)));
263 if(!t1)
return std::unexpected(t1.error());
265 auto t2 = parseRouteArgAs<typename std::tuple_element<0, TupleT>::type>(server::RouteArg(*defs.at(2), values_str.at(2)));
266 if(!t2)
return std::unexpected(t2.error());
268 return std::make_tuple(*t0, *t1, *t2);
272 template <IsTupleLike TupleT>
273 struct TupleParser<TupleT, 4>
275 parse::Result<TupleT> operator()(
const std::vector<std::unique_ptr<dcn::server::RouteArgDef>> &defs,
const std::vector<std::string> & values_str)
280 auto t0 = parseRouteArgAs<typename std::tuple_element<0, TupleT>::type>(server::RouteArg(*defs.at(0), values_str.at(0)));
281 if(!t0)
return std::unexpected(t0.error());
283 auto t1 = parseRouteArgAs<typename std::tuple_element<0, TupleT>::type>(server::RouteArg(*defs.at(1), values_str.at(1)));
284 if(!t1)
return std::unexpected(t1.error());
286 auto t2 = parseRouteArgAs<typename std::tuple_element<0, TupleT>::type>(server::RouteArg(*defs.at(2), values_str.at(2)));
287 if(!t2)
return std::unexpected(t2.error());
289 auto t3 = parseRouteArgAs<typename std::tuple_element<0, TupleT>::type>(server::RouteArg(*defs.at(3), values_str.at(3)));
290 if(!t3)
return std::unexpected(t3.error());
292 return std::make_tuple(*t0, *t1, *t2, *t3);
297 template<IsTupleLike TupleT>
298 parse::Result<TupleT> parseRouteArgAs(
const server::RouteArg& arg)
304 std::string data = arg.getData();
310 data = data.substr(1, data.size() - 2);
313 std::vector<std::string> values_str;
314 std::size_t begin = 0;
317 while ((end = data.find(OBJECT_FIELDS_DELIMETER, begin)) != std::string::npos) {
318 values_str.push_back(data.substr(begin, (end - begin)));
322 values_str.push_back(data.substr(begin));
324 return TupleParser<TupleT, std::tuple_size<TupleT>::value>{}(arg.getChildren(), values_str);
327 template<IsSequenceContainer ContainerT>
328 parse::Result<ContainerT> parseRouteArgAs(
const server::RouteArg& arg)
330 using T =
typename ContainerT::value_type;
336 std::string data = arg.getData();
342 data = data.substr(1, data.size() - 2);
345 constexpr static const char array_values_delimeter =
',';
347 std::vector<std::string> values_str;
348 std::size_t begin = 0;
351 while ((end = data.find(array_values_delimeter, begin)) != std::string::npos) {
352 values_str.push_back(data.substr(begin, (end - begin)));
356 values_str.push_back(data.substr(begin));
359 const auto & array_type = *arg.getChildren().at(0);
361 for (
const auto & value_str : values_str)
363 server::RouteArg array_value = server::RouteArg(array_type, value_str);
364 const auto parsed_value = parseRouteArgAs<T>(array_value);
365 if(!parsed_value)
return std::unexpected(parsed_value.error());
367 values.emplace_back(*parsed_value);
375struct std::formatter<
dcn::server::RouteArgType> : std::formatter<std::string> {
389 return formatter<string>::format(
"", ctx);
394struct std::formatter<
dcn::server::RouteArgRequirement> : std::formatter<std::string> {
404 return formatter<string>::format(
"", ctx);
409struct std::formatter<
dcn::server::RouteArg> : std::formatter<std::string> {
411 return formatter<string>::format(
A class representing a route argument.
Definition route_arg.hpp:94
const std::vector< std::unique_ptr< RouteArgDef > > & getChildren() const
Gets the children of the route argument.
Definition route_arg.cpp:27
RouteArgRequirement getRequirement() const
Gets the requirement of the route argument.
Definition route_arg.cpp:22
RouteArgType getType() const
Gets the type of the route argument.
Definition route_arg.cpp:12
const std::string & getData() const
Gets the data associated with the route argument.
Definition route_arg.cpp:17
Definition route_arg.hpp:145
Definition route_arg.hpp:152
Definition route_arg.hpp:169
RouteArgRequirement
Enum to represent the requirement of a route argument.
Definition route_arg.hpp:42
RouteArgType
Enum to represent the type of a route argument.
Definition route_arg.hpp:24
Definition decentralised_art.hpp:30
Definition parse_error.hpp:11
A pair of RouteArgType and RouteArgRequirement.
Definition route_arg.hpp:57
RouteArgDef(RouteArgDef &&other) noexcept
Definition route_arg.hpp:79
RouteArgDef(RouteArgType type, RouteArgRequirement requirement)
Definition route_arg.hpp:58
std::vector< std::unique_ptr< RouteArgDef > > children
Definition route_arg.hpp:84
RouteArgType type
Definition route_arg.hpp:82
RouteArgDef(const RouteArgDef &other)
Definition route_arg.hpp:65
RouteArgDef(RouteArgType type, RouteArgRequirement requirement, std::vector< std::unique_ptr< RouteArgDef > > children)
Definition route_arg.hpp:61
RouteArgRequirement requirement
Definition route_arg.hpp:83