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() ? std::nullopt
27 : std::optional{Error{Error::Types::ERR_ALREADY_INVALID, pck.getReadPos(),
28 "already invalid packet", __func__}})
31constexpr ChainedArguments<TValue>::ChainedArguments(Packet
const& pck,
32 std::optional<Error>&& err,
33 TValue* existingValue) :
35 g_value(existingValue == nullptr ? Value{std::in_place_type<TValue>} : Value{existingValue}),
36 g_error(std::move(err))
42 auto* value = std::holds_alternative<TValue>(this->g_value) ? &std::get<TValue>(this->g_value)
43 : std::get<TValue*>(this->g_value);
44 *this->g_pck >> *value;
45 if (this->g_pck->isValid())
50 net::Error{net::Error::Types::ERR_EXTRACT, this->g_pck->getReadPos(),
"extraction failed", __func__};
57 auto startReadPos = this->g_pck->getReadPos();
60 *this->g_pck >> value;
62 if (this->g_pck->isValid())
64 this->g_pck->setReadPos(startReadPos);
68 this->g_error =
net::Error{net::Error::Types::ERR_EXTRACT, this->g_pck->getReadPos(),
"peek failed", __func__};
78constexpr Packet const& ChainedArguments<TValue>::packet()
const
83constexpr TValue
const& ChainedArguments<TValue>::value()
const
85 return std::holds_alternative<TValue>(this->g_value) ? std::get<TValue>(this->g_value)
86 : *std::get<TValue*>(this->g_value);
89constexpr TValue& ChainedArguments<TValue>::value()
91 return std::holds_alternative<TValue>(this->g_value) ? std::get<TValue>(this->g_value)
92 : *std::get<TValue*>(this->g_value);
96template<
class TInvokable>
97constexpr typename std::invoke_result_t<TInvokable, ChainedArguments<TValue>&>
100 if (this->g_pck->isValid())
102 return std::invoke(std::forward<TInvokable>(f), *
this);
104 return {*this->g_pck, std::move(this->g_error),
nullptr};
106template<
class TValue>
107template<
class TInvokable,
class TIndex>
111 if (!this->g_pck->isValid())
116 for (; iStart != iEnd; iStart += iIncrement)
118 std::optional<Error> err =
119 std::invoke(std::forward<TInvokable>(f),
const_cast<ChainedArguments<TValue> const&
>(*
this), iStart);
129template<
class TValue>
130template<
class TInvokable,
class TIndex>
134 if (!this->g_pck->isValid())
139 auto& value = this->value();
141 for (; iStart != value; iStart += iIncrement)
143 std::optional<Error> err =
144 std::invoke(std::forward<TInvokable>(f),
const_cast<ChainedArguments<TValue> const&
>(*
this), iStart);
154template<
class TValue>
155template<
class TInvokable>
158 if (!this->g_pck->isValid())
163 auto& value = this->value();
165 for (TValue iIndex = 0; iIndex != value; ++iIndex)
167 std::optional<Error> err =
168 std::invoke(std::forward<TInvokable>(f),
const_cast<ChainedArguments<TValue> const&
>(*
this), iIndex);
178template<
class TValue>
179template<
class TInvokable>
182 if (!this->g_pck->isValid())
184 std::invoke(std::forward<TInvokable>(f), *
this);
185 return this->g_error;
189template<
class TValue>
192 return this->g_pck->isValid() ? std::nullopt : std::optional<Error>{std::move(this->g_error)};
194template<
class TValue>
197 return this->g_pck->isValid() && this->g_pck->endReached() ? std::nullopt
198 : std::optional<Error>{std::move(this->g_error)};
200template<
class TValue>
205template<
class TValue>
208 return Error{Error::Types::ERR_EXTRACT, this->g_pck->getReadPos(), error, function};
211template<
class TValue>
214 if (this->g_pck->isValid())
216 auto* extractedValue = std::holds_alternative<TValue>(this->g_value) ? &std::get<TValue>(this->g_value)
217 : std::get<TValue*>(this->g_value);
218 if constexpr (std::is_move_assignable_v<TValue>)
220 value = std::move(*extractedValue);
224 value = *extractedValue;
229template<
class TValue>
230template<
class TInvokable>
233 if (this->g_pck->isValid())
235 auto* extractedValue = std::holds_alternative<TValue>(this->g_value) ? &std::get<TValue>(this->g_value)
236 : std::get<TValue*>(this->g_value);
237 std::invoke(std::forward<TInvokable>(f),
const_cast<TValue&
>(*extractedValue));
242template<
class TValue>
245 this->g_error = std::move(err);
248template<
class TValue>
251 this->g_pck->invalidate();
252 this->g_error = std::move(err);
255template<
class TValue>
258 this->g_pck->invalidate();
259 this->g_error =
Error{Error::Types::ERR_EXTRACT, this->g_pck->getReadPos(), error, function};
263template<
class TValue, ROutputs TOutput>
266 if (args.packet().isValid())
268 auto* val = args.extract();
271 if (!((*val >= min && *val <= max) ^
static_cast<bool>(TOutput)))
273 args.invalidate(
Error{Error::Types::ERR_RULE, args.packet().getReadPos(),
"rule failed", __func__});
280template<
class TValue>
283 if (args.packet().isValid())
285 auto* val = args.extract();
288 args.invalidate(
Error{Error::Types::ERR_RULE, args.packet().getReadPos(),
"rule failed", __func__});
294template<
class TValue, ROutputs TOutput>
297 if (args.packet().isValid())
299 auto* val = args.extract();
302 if (!((*val == a) ^
static_cast<bool>(TOutput)))
304 args.invalidate(
Error{Error::Types::ERR_RULE, args.packet().getReadPos(),
"rule failed", __func__});
311template<
class TValue, ROutputs TOutput>
314 if (args.packet().isValid())
316 auto* val = args.extract();
319 if (!((*val < less) ^
static_cast<bool>(TOutput)))
321 args.invalidate(
Error{Error::Types::ERR_RULE, args.packet().getReadPos(),
"rule failed", __func__});
328template<
class TValue, ROutputs TOutput>
331 if (args.packet().isValid())
333 auto* val = args.extract();
336 if (!((*val <= less) ^
static_cast<bool>(TOutput)))
338 args.invalidate(
Error{Error::Types::ERR_RULE, args.packet().getReadPos(),
"rule failed", __func__});
345template<
class TValue, ROutputs TOutput>
348 if (args.packet().isValid())
350 auto size = args.template peek<SizeType>();
353 if (!((size >= min && size <= max) ^
static_cast<bool>(TOutput)))
355 args.invalidate(
Error{Error::Types::ERR_RULE, args.packet().getReadPos(),
"rule failed", __func__});
362template<
class TValue, ROutputs TOutput>
365 if (args.packet().isValid())
367 auto size = args.template peek<SizeType>();
370 if (!((size == a) ^
static_cast<bool>(TOutput)))
372 args.invalidate(
Error{Error::Types::ERR_RULE, args.packet().getReadPos(),
"rule failed", __func__});
379template<
class TValue, ROutputs TOutput>
382 if (args.packet().isValid())
384 auto* val = args.extract();
389 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:243
constexpr std::optional< TPeek > peek()
Peek without changing the read position a copy of value.
Definition network_manager.inl:55
constexpr std::optional< Error > skip() const
Helper to "continue" in a and_for_each() loop without returning an error.
Definition network_manager.inl:201
constexpr std::optional< Error > final()
End the chain by doing a last validity check on the packet.
Definition network_manager.inl:195
constexpr ChainedArguments< TValue > & apply(TValue &value)
Apply the extracted value to the provided reference.
Definition network_manager.inl:212
constexpr TValue * extract()
Extract and verify the value from the packet.
Definition network_manager.inl:40
constexpr std::invoke_result_t< TInvokable, ChainedArguments< TValue > & > and_then(TInvokable &&f)
Chain up some code after a successful extraction.
Definition network_manager.inl:98
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:109
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:206
constexpr std::optional< Error > on_error(TInvokable &&f)
Chain up some code after an unsuccessful extraction.
Definition network_manager.inl:180
constexpr std::optional< Error > end()
End the chain by doing a last validity check on the packet.
Definition network_manager.inl:190
constexpr ChainedArguments< TValue > & invalidate(Error &&err)
Invalidate the packet and set the error.
Definition network_manager.inl:249
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:264
constexpr ChainedArguments< TValue > RMustValidUtf8(ChainedArguments< TValue > &&args)
Check if the extracted string is a valid UTF8 string.
Definition network_manager.inl:380
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:312
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:295
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:363
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:346
constexpr ChainedArguments< TValue > RValid(ChainedArguments< TValue > &&args)
Valid rule, check if the value is correctly extracted.
Definition network_manager.inl:281
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:329
Definition C_error.hpp:28