Skip to content

Commit 765f455

Browse files
committed
WIP: Composite CustomMessageHandler macro
A CustomMessageHandler may be used to implement an extension to the BOLT specs. Using more than one custom handler requires defining a wrapper for both the handlers and their CustomMessage associated type. Define a macro that takes care of this boilerplate.
1 parent 6957fb6 commit 765f455

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

lightning/src/ln/peer_handler.rs

+77
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,85 @@ pub trait CustomMessageHandler: wire::CustomMessageReader {
6060
fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)>;
6161
}
6262

63+
macro_rules! composite_custom_message_handler {
64+
(
65+
$handler_visibility:vis struct $handler:ident {
66+
$($field_visibility:vis $field:ident: $type:ty),* $(,)*
67+
}
68+
69+
$message_visibility:vis enum $message:ident {
70+
$($variant:ident($range:pat)),* $(,)*
71+
}
72+
) => {
73+
#[allow(missing_docs)]
74+
$handler_visibility struct $handler {
75+
$(
76+
$field_visibility $field: $type,
77+
)*
78+
}
79+
80+
#[allow(missing_docs)]
81+
#[derive(Debug)]
82+
$message_visibility enum $message {
83+
$(
84+
$variant(<$type as wire::CustomMessageReader>::CustomMessage),
85+
)*
86+
}
87+
88+
impl wire::CustomMessageReader for $handler {
89+
type CustomMessage = $message;
90+
fn read<R: io::Read>(
91+
&self, message_type: u16, buffer: &mut R
92+
) -> Result<Option<Self::CustomMessage>, msgs::DecodeError> {
93+
match message_type {
94+
$(
95+
$range => match <$type>::read(&self.$field, message_type, buffer)? {
96+
None => unreachable!(),
97+
Some(message) => Ok(Some($message::$variant(message))),
98+
},
99+
)*
100+
_ => Ok(None),
101+
}
102+
}
103+
}
104+
105+
impl wire::Type for $message {
106+
fn type_id(&self) -> u16 {
107+
match self {
108+
$(
109+
Self::$variant(message) => message.type_id(),
110+
)*
111+
}
112+
}
113+
}
114+
115+
impl Writeable for $message {
116+
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
117+
match self {
118+
$(
119+
Self::$variant(message) => message.write(writer),
120+
)*
121+
}
122+
}
123+
}
124+
}
125+
}
126+
127+
composite_custom_message_handler!(
128+
pub struct CompositeMessageHandler {
129+
ignoring: IgnoringMessageHandler,
130+
ignoring2: IgnoringMessageHandler,
131+
}
132+
133+
pub enum CompositeMessage {
134+
Infallible(0),
135+
Infallible2(1..=10),
136+
}
137+
);
138+
63139
/// A dummy struct which implements `RoutingMessageHandler` without storing any routing information
64140
/// or doing any processing. You can provide one of these as the route_handler in a MessageHandler.
141+
#[derive(Debug)]
65142
pub struct IgnoringMessageHandler{}
66143
impl MessageSendEventsProvider for IgnoringMessageHandler {
67144
fn get_and_clear_pending_msg_events(&self) -> Vec<MessageSendEvent> { Vec::new() }

0 commit comments

Comments
 (0)