23constexpr ChainedArguments<TValue>::ChainedArguments(Packet
const& pck, TValue* existingValue) :
25 g_value(existingValue == nullptr ? Value{std::in_place_type<TValue>} : Value{existingValue}),
26 g_error(pck.isValid() ? Error{}
27 : Error{Error::Types::ERR_ALREADY_INVALID, pck.getReadPos(),
"already invalid packet",
31constexpr ChainedArguments<TValue>::ChainedArguments(Packet
const& pck, Error&& err, TValue* existingValue) :
33 g_value(existingValue == nullptr ? Value{std::in_place_type<TValue>} : Value{existingValue}),
34 g_error(std::move(err))
40 auto* value = std::holds_alternative<TValue>(this->g_value) ? &std::get<TValue>(this->g_value)
41 : std::get<TValue*>(this->g_value);
42 *this->g_pck >> *value;
43 if (this->g_pck->isValid())
48 net::Error{net::Error::Types::ERR_EXTRACT, this->g_pck->getReadPos(),
"extraction failed", __func__};
55 auto startReadPos = this->g_pck->getReadPos();
58 *this->g_pck >> value;
60 if (this->g_pck->isValid())
62 this->g_pck->setReadPos(startReadPos);
66 this->g_error =
net::Error{net::Error::Types::ERR_EXTRACT, this->g_pck->getReadPos(),
"peek failed", __func__};
76constexpr Packet const& ChainedArguments<TValue>::packet()
const
81constexpr TValue
const& ChainedArguments<TValue>::value()
const
83 return std::holds_alternative<TValue>(this->g_value) ? std::get<TValue>(this->g_value)
84 : *std::get<TValue*>(this->g_value);
87constexpr TValue& ChainedArguments<TValue>::value()
89 return std::holds_alternative<TValue>(this->g_value) ? std::get<TValue>(this->g_value)
90 : *std::get<TValue*>(this->g_value);
94template<
class TInvokable>
95constexpr typename std::invoke_result_t<TInvokable, ChainedArguments<TValue>&>
98 if (this->g_pck->isValid())
100 return std::invoke(std::forward<TInvokable>(f), *
this);
102 return {*this->g_pck, std::move(this->g_error),
nullptr};
104template<
class TValue>
105template<
class TInvokable,
class TIndex>
109 if (!this->g_pck->isValid())
114 for (; iStart != iEnd; iStart += iIncrement)
116 std::optional<Error> err =
117 std::invoke(std::forward<TInvokable>(f),
const_cast<ChainedArguments<TValue> const&
>(*
this), iStart);
127template<
class TValue>
128template<
class TInvokable,
class TIndex>
132 if (!this->g_pck->isValid())
137 auto& value = this->value();
139 for (; iStart != value; iStart += iIncrement)
141 std::optional<Error> err =
142 std::invoke(std::forward<TInvokable>(f),
const_cast<ChainedArguments<TValue> const&
>(*
this), iStart);
152template<
class TValue>
153template<
class TInvokable>
156 if (!this->g_pck->isValid())
161 auto& value = this->value();
163 for (TValue iIndex = 0; iIndex != value; ++iIndex)
165 std::optional<Error> err =
166 std::invoke(std::forward<TInvokable>(f),
const_cast<ChainedArguments<TValue> const&
>(*
this), iIndex);
176template<
class TValue>
177template<
class TInvokable>
180 if (!this->g_pck->isValid())
182 std::invoke(std::forward<TInvokable>(f), *
this);
183 return this->g_error;
187template<
class TValue>
190 return this->g_pck->isValid() ? std::nullopt : std::optional<Error>{std::move(this->g_error)};
192template<
class TValue>
195 return this->g_pck->isValid() && this->g_pck->endReached() ? std::nullopt
196 : std::optional<Error>{std::move(this->g_error)};
198template<
class TValue>
203template<
class TValue>
206 return Error{Error::Types::ERR_EXTRACT, this->g_pck->getReadPos(), error, function};
209template<
class TValue>
212 if (this->g_pck->isValid())
214 auto* extractedValue = std::holds_alternative<TValue>(this->g_value) ? &std::get<TValue>(this->g_value)
215 : std::get<TValue*>(this->g_value);
216 if constexpr (std::is_move_assignable_v<TValue>)
218 value = std::move(*extractedValue);
222 value = *extractedValue;
227template<
class TValue>
228template<
class TInvokable>
231 if (this->g_pck->isValid())
233 auto* extractedValue = std::holds_alternative<TValue>(this->g_value) ? &std::get<TValue>(this->g_value)
234 : std::get<TValue*>(this->g_value);
235 std::invoke(std::forward<TInvokable>(f),
const_cast<TValue&
>(*extractedValue));
240template<
class TValue>
243 this->g_error = std::move(err);
246template<
class TValue>
249 this->g_pck->invalidate();
250 this->g_error = std::move(err);
253template<
class TValue>
256 this->g_pck->invalidate();
257 this->g_error =
Error{Error::Types::ERR_EXTRACT, this->g_pck->getReadPos(), error, function};
261template<
class TValue, ROutputs TOutput>
264 if (args.packet().isValid())
266 auto* val = args.extract();
269 if (!((*val >= min && *val <= max) ^
static_cast<bool>(TOutput)))
271 args.invalidate(
Error{Error::Types::ERR_RULE, args.packet().getReadPos(),
"rule failed", __func__});
278template<
class TValue>
281 if (args.packet().isValid())
283 auto* val = args.extract();
286 args.invalidate(
Error{Error::Types::ERR_RULE, args.packet().getReadPos(),
"rule failed", __func__});
292template<
class TValue, ROutputs TOutput>
295 if (args.packet().isValid())
297 auto* val = args.extract();
300 if (!((*val == a) ^
static_cast<bool>(TOutput)))
302 args.invalidate(
Error{Error::Types::ERR_RULE, args.packet().getReadPos(),
"rule failed", __func__});
309template<
class TValue, ROutputs TOutput>
312 if (args.packet().isValid())
314 auto* val = args.extract();
317 if (!((*val < less) ^
static_cast<bool>(TOutput)))
319 args.invalidate(
Error{Error::Types::ERR_RULE, args.packet().getReadPos(),
"rule failed", __func__});
326template<
class TValue, ROutputs TOutput>
329 if (args.packet().isValid())
331 auto* val = args.extract();
334 if (!((*val <= less) ^
static_cast<bool>(TOutput)))
336 args.invalidate(
Error{Error::Types::ERR_RULE, args.packet().getReadPos(),
"rule failed", __func__});
343template<
class TValue, ROutputs TOutput>
346 if (args.packet().isValid())
348 auto size = args.template peek<SizeType>();
351 if (!((size >= min && size <= max) ^
static_cast<bool>(TOutput)))
353 args.invalidate(
Error{Error::Types::ERR_RULE, args.packet().getReadPos(),
"rule failed", __func__});
360template<
class TValue, ROutputs TOutput>
363 if (args.packet().isValid())
365 auto size = args.template peek<SizeType>();
368 if (!((size == a) ^
static_cast<bool>(TOutput)))
370 args.invalidate(
Error{Error::Types::ERR_RULE, args.packet().getReadPos(),
"rule failed", __func__});
377template<
class TValue, ROutputs TOutput>
380 if (args.packet().isValid())
382 auto* val = args.extract();
387 args.invalidate(
Error{Error::Types::ERR_RULE, args.packet().getReadPos(),
"rule failed", __func__});
Definition C_packet.hpp:52
This is a wrapper around a Packet and a value for safe extraction.
Definition network_manager.hpp:74
constexpr ChainedArguments< TValue > & setError(Error &&err)
Set the error.
Definition network_manager.inl:241
constexpr std::optional< TPeek > peek()
Peek without changing the read position a copy of value.
Definition network_manager.inl:53
constexpr std::optional< Error > skip() const
Helper to "continue" in a and_for_each() loop without returning an error.
Definition network_manager.inl:199
constexpr std::optional< Error > final()
End the chain by doing a last validity check on the packet.
Definition network_manager.inl:193
constexpr ChainedArguments< TValue > & apply(TValue &value)
Apply the extracted value to the provided reference.
Definition network_manager.inl:210
constexpr TValue * extract()
Extract and verify the value from the packet.
Definition network_manager.inl:38
constexpr std::invoke_result_t< TInvokable, ChainedArguments< TValue > & > and_then(TInvokable &&f)
Chain up some code after a successful extraction.
Definition network_manager.inl:96
constexpr ChainedArguments< TValue > & and_for_each(TIndex iStart, TIndex iEnd, TIndex iIncrement, TInvokable &&f)
Chain up some code in a for loop after a successful extraction.
Definition network_manager.inl:107
constexpr std::optional< Error > stop(char const *error, char const *function) const
Helper to "break" in a and_for_each() loop with a custom error.
Definition network_manager.inl:204
constexpr std::optional< Error > on_error(TInvokable &&f)
Chain up some code after an unsuccessful extraction.
Definition network_manager.inl:178
constexpr std::optional< Error > end()
End the chain by doing a last validity check on the packet.
Definition network_manager.inl:188
constexpr ChainedArguments< TValue > & invalidate(Error &&err)
Invalidate the packet and set the error.
Definition network_manager.inl:247
constexpr ChainedArguments< TValue > RRange(TValue const &min, TValue const &max, ChainedArguments< TValue > &&args)
Range rule, check if the value is in the min/max range.
Definition network_manager.inl:262
constexpr ChainedArguments< TValue > RMustValidUtf8(ChainedArguments< TValue > &&args)
Check if the extracted string is a valid UTF8 string.
Definition network_manager.inl:378
constexpr ChainedArguments< TValue > RStrictLess(TValue less, ChainedArguments< TValue > &&args)
Strict less rule, check if the value is strictly lesser than the provided one.
Definition network_manager.inl:310
constexpr ChainedArguments< TValue > RMustEqual(TValue const &a, ChainedArguments< TValue > &&args)
Must equal rule, check if the value is equal to the provided one.
Definition network_manager.inl:293
constexpr ChainedArguments< TValue > RSizeMustEqual(SizeType a, ChainedArguments< TValue > &&args)
Size must equal rule, check if the size is equal to the provided one.
Definition network_manager.inl:361
constexpr ChainedArguments< TValue > RSizeRange(SizeType min, SizeType max, ChainedArguments< TValue > &&args)
Size range rule, check if the size is in the min/max range.
Definition network_manager.inl:344
constexpr ChainedArguments< TValue > RValid(ChainedArguments< TValue > &&args)
Valid rule, check if the value is correctly extracted.
Definition network_manager.inl:279
constexpr ChainedArguments< TValue > RLess(TValue less, ChainedArguments< TValue > &&args)
Less rule, check if the value is lesser than the provided one.
Definition network_manager.inl:327
Definition C_error.hpp:28