macro_rules! named_codes {
(
$(#[$meta:meta])*
pub struct $Name:ident($inner:ty);
$(
$(#[$vmeta:meta])*
const $VARIANT:ident = $val:expr_2021;
)*
) => {
$(#[$meta])*
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct $Name($inner);
impl $Name {
$(
$(#[$vmeta])*
#[doc = ""]
#[doc = concat!("Wire value `", stringify!($val), "`.")]
pub const $VARIANT: Self = Self($val);
)*
pub const ALL_NAMED: &[(&str, Self)] = &[
$( (stringify!($VARIANT), Self($val)), )*
];
#[inline]
#[must_use]
pub const fn from_raw(value: $inner) -> Self {
Self(value)
}
#[inline]
#[must_use]
pub const fn to_raw(self) -> $inner {
self.0
}
#[must_use]
pub const fn name(self) -> Option<&'static str> {
match self.0 {
$( $val => Some(stringify!($VARIANT)), )*
_ => None,
}
}
#[must_use]
pub const fn is_defined(self) -> bool {
self.name().is_some()
}
}
impl core::fmt::Debug for $Name {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self.name() {
Some(name) => write!(f, "{}::{}", stringify!($Name), name),
None => write!(f, "{}({})", stringify!($Name), self.0),
}
}
}
impl core::fmt::Display for $Name {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self.name() {
Some(name) => f.write_str(name),
None => write!(f, "{}", self.0),
}
}
}
};
}
named_codes! {
pub struct NetworkMessageType(u8);
const I_AM_ROUTER_TO_NETWORK = 0x01;
const I_COULD_BE_ROUTER_TO_NETWORK = 0x02;
const REJECT_MESSAGE_TO_NETWORK = 0x03;
const WHO_IS_ROUTER_TO_NETWORK = 0x00;
const ROUTER_AVAILABLE_TO_NETWORK = 0x05;
const ROUTER_BUSY_TO_NETWORK = 0x04;
const INITIALIZE_ROUTING_TABLE = 0x06;
const INITIALIZE_ROUTING_TABLE_ACK = 0x07;
const DISCONNECT_CONNECTION_TO_NETWORK = 0x09;
const ESTABLISH_CONNECTION_TO_NETWORK = 0x08;
const NETWORK_NUMBER_IS = 0x13;
const WHAT_IS_NETWORK_NUMBER = 0x12;
}
impl NetworkMessageType {
#[must_use]
pub const fn is_proprietary(self) -> bool {
self.to_raw() >= 0x80
}
#[must_use]
pub const fn is_removed_security(self) -> bool {
matches!(self.to_raw(), 0x0A..=0x11)
}
}
named_codes! {
pub struct RejectMessageReason(u8);
const OTHER = 0;
const NOT_DIRECTLY_CONNECTED = 1;
const ROUTER_BUSY = 2;
const UNKNOWN_MESSAGE_TYPE = 3;
const MESSAGE_TOO_LONG = 4;
const ADDRESSING_ERROR = 6;
}