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    Subscribe { flags, stream_id, channel, accepted_schemas, max_in_flight },
54    SubscribeAck { flags, stream_id, subscription_id, selected_schema },
55    SubscribeError { flags, stream_id, reason_code, message },
56    Unsubscribe { flags, stream_id, subscription_id },
57    Publish { flags, stream_id, channel, envelope, idempotency_key },
58    PublishAck { flags, stream_id, message_id, durable_position },
59    PublishError { flags, stream_id, reason_code, message },
60    ConversationOpen { flags, stream_id, conversation_id, subject },
61    ConversationMessage { flags, stream_id, conversation_id, envelope },
62    ConversationClose { flags, stream_id, conversation_id, reason_code, message },
63    ConversationError { flags, stream_id, conversation_id, reason_code, message },
64    Accept { flags, stream_id, referenced_message_id },
65    Defer { flags, stream_id, referenced_message_id, reason },
66    Reject { flags, stream_id, referenced_message_id, reason },
67    Ping { flags },
68    Pong { flags },
69    Push { flags, stream_id, correlation_id, payload },
70    PushReply { flags, stream_id, correlation_id, payload },
71    WorkerRegister { flags, registration },
72    WorkerRegisterAck { flags, outcome },
73    Deliver { flags, stream_id, delivery_seq, envelope, message },
74    Unknown { type_id, flags, stream_id, payload },
75}