Flatten nested frames¶
A frame whose payload is another frame nests as deep as the protocol does. flatten() hands back every
header on the way down and the innermost payload in one structured binding.
Source: example/howto/flatten.cpp, CMake target howto_flatten.
enum class msg_type : std::uint8_t { order = 1, cancel = 2 };
// transport: a length-prefixed block...
struct [[=rbe::pack_be]] TransportHeader {
[[=rbe::payload_length]] std::uint16_t length;
std::uint32_t session;
};
// ...holding one message, whose own header picks the type
struct [[=rbe::pack_be]] MessageHeader {
[[=rbe::id]] msg_type type;
std::uint32_t sequence;
};
struct [[=rbe::pack_be, =rbe::id(msg_type::order)]] Order { std::uint32_t order_id; std::uint64_t price; };
struct [[=rbe::pack_be, =rbe::id(msg_type::cancel)]] Cancel { std::uint32_t order_id; };
using message = rbe::frames::frame<MessageHeader, rbe::frames::any<Order, Cancel>>;
using block = rbe::frames::frame<TransportHeader, message>; // a frame whose payload is a frame
Level by level¶
auto blk = rbe::deserialize<block>(bytes);
auto session = blk.header().field<"session">();
auto sequence = blk.payload().header().field<"sequence">(); // one level down
auto payload = blk.payload().payload(); // two levels down: the any
All at once¶
auto blk = rbe::deserialize<block>(bytes);
// every header on the way down, then the innermost payload
auto const [transport, header, payload] = blk.flatten();
std::println("session {} sequence {}", transport.field<"session">(), header.field<"sequence">());
payload.match(
[](Order const& order) { std::println("order {} @ {}", order.order_id, order.price); },
[](Cancel const& cancel) { std::println("cancel {}", cancel.order_id); },
[](rbe::unmatched auto) { std::println("unknown"); }
);
// the block knows its extent: the transport header declares the payload length
std::size_t length = blk.length(); // header plus payload
std::size_t same = rbe::frames::length(blk); // the function object, for generic code
flatten stops at a payload that is not a frame: a struct, an any, a many or a blob. A frame holding
a run therefore flattens to its header and the run.
See also: Frames reference, frame view.