Skip to main content

liminal/protocol/frame/
debug.rs

1//! `Frame`'s `Debug`, written by hand (ACCESS-004 R5).
2//!
3//! A `Connect` carries a credential, a bearer token or a whole registry
4//! pass, so its `Debug` names `auth_token` by its length only. Every other
5//! variant prints exactly what the derived `Debug` printed: its name and
6//! each field, in declaration order, listed once below.
7
8use core::fmt;
9
10use super::Frame;
11
12/// A credential field: its length, never its bytes.
13struct ByteLength(usize);
14
15impl fmt::Debug for ByteLength {
16    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
17        write!(formatter, "{} bytes", self.0)
18    }
19}
20
21macro_rules! frame_debug {
22    ($($variant:ident { $($field:ident),* }),* $(,)?) => {
23        impl fmt::Debug for Frame {
24            fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
25                match self {
26                    Self::Connect {
27                        flags,
28                        min_version,
29                        max_version,
30                        auth_token,
31                    } => formatter
32                        .debug_struct("Connect")
33                        .field("flags", flags)
34                        .field("min_version", min_version)
35                        .field("max_version", max_version)
36                        .field("auth_token", &ByteLength(auth_token.len()))
37                        .finish(),
38                    $(Self::$variant { $($field),* } => {
39                        let mut out = formatter.debug_struct(stringify!($variant));
40                        $(out.field(stringify!($field), $field);)*
41                        out.finish()
42                    })*
43                }
44            }
45        }
46    };
47}
48
49frame_debug! {
50    ConnectAck { flags, selected_version, capabilities },
51    ConnectError { flags, reason_code, message },
52    Disconnect { flags },
53    DisconnectReason { flags, reason },
54    Subscribe { flags, stream_id, channel, accepted_schemas, max_in_flight },
55    SubscribeAck { flags, stream_id, subscription_id, selected_schema },
56    SubscribeError { flags, stream_id, reason_code, message },
57    Unsubscribe { flags, stream_id, subscription_id },
58    Publish { flags, stream_id, channel, envelope, idempotency_key },
59    PublishAck { flags, stream_id, message_id, durable_position },
60    PublishError { flags, stream_id, reason_code, message },
61    ConversationOpen { flags, stream_id, conversation_id, subject },
62    ConversationMessage { flags, stream_id, conversation_id, envelope },
63    ConversationClose { flags, stream_id, conversation_id, reason_code, message },
64    ConversationError { flags, stream_id, conversation_id, reason_code, message },
65    Accept { flags, stream_id, referenced_message_id },
66    Defer { flags, stream_id, referenced_message_id, reason },
67    Reject { flags, stream_id, referenced_message_id, reason },
68    Ping { flags },
69    Pong { flags },
70    Push { flags, stream_id, correlation_id, payload },
71    PushReply { flags, stream_id, correlation_id, payload },
72    WorkerRegister { flags, registration },
73    WorkerRegisterAck { flags, outcome },
74    Deliver { flags, stream_id, delivery_seq, envelope, message },
75    LinkOpen { flags, stream_id, offer },
76    LinkOpenAck { flags, stream_id, outcome },
77    LinkMessage { flags, stream_id, subject, sealed },
78    Unknown { type_id, flags, stream_id, payload },
79}