Skip to content

Commit

Permalink
type enums everywhere
Browse files Browse the repository at this point in the history
  • Loading branch information
density215 committed Jul 5, 2023
1 parent 3b70710 commit 36ce718
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 73 deletions.
76 changes: 34 additions & 42 deletions src/bmp/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,12 +373,7 @@ impl<Octets: AsRef<[u8]>> PerPeerHeader<Octets> {
/// Returns the peer type as defined in
/// [RFC7854](https://datatracker.ietf.org/doc/html/rfc7854#section-10.2).
pub fn peer_type(&self) -> PeerType {
match self.octets.as_ref()[0] {
0 => PeerType::GlobalInstance,
1 => PeerType::RdInstance,
2 => PeerType::LocalInstance,
_ => PeerType::Undefined,
}
self.octets.as_ref()[0].into()
}

// 0 1 2 3 4 5 6 7
Expand Down Expand Up @@ -511,22 +506,26 @@ impl<Octets: AsRef<[u8]>> PartialEq for PerPeerHeader<Octets> {
}
}

/// The three peer types as defined in
/// [RFC7854](https://datatracker.ietf.org/doc/html/rfc7854#section-4.2).
#[derive(Debug, Hash, Eq, PartialEq)]
pub enum PeerType {
GlobalInstance,
RdInstance,
LocalInstance,
Undefined,
}
typeenum!(
/// The peer types as defined in
/// https://www.iana.org/assignments/bmp-parameters/bmp-parameters.xhtml#peer-types
PeerType, u8,
0 => GlobalInstance,
1 => RdInstance,
2 => LocalInstance,
3 => LocalRibInstance;
4..=250 => Unassigned;
251..=254 => Experimental;
255 => Reserved
);

/// Specify which RIB the contents of a message originated from.
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
pub enum RibType {
AdjRibIn,
AdjRibOut,
}

typeenum!(
/// Specify which RIB the contents of a message originated from.
RibType, u8,
0 => AdjRibIn,
1 => AdjRibOut
);


//--- Specific Message types -------------------------------------------------
Expand Down Expand Up @@ -1068,14 +1067,7 @@ impl<'a> InformationTlv<'a> {

/// Returns the `InformationTlvType` for this TLV.
pub fn typ(&self) -> InformationTlvType {
match u16::from_be_bytes(self.octets[0..=1].try_into().unwrap()) {
0 => InformationTlvType::String,
1 => InformationTlvType::SysDesc,
2 => InformationTlvType::SysName,
3 => InformationTlvType::VrfTableName,
4 => InformationTlvType::AdminLabel,
u => InformationTlvType::Undefined(u)
}
InformationTlvType::from(u16::from_be_bytes(self.octets[0..=1].try_into().unwrap()))
}

/// Returns the length of the value.
Expand Down Expand Up @@ -1105,19 +1097,19 @@ impl<'a> Display for InformationTlv<'a> {

}

/// Types of Information TLVs.
///
/// See also
/// <https://www.iana.org/assignments/bmp-parameters/bmp-parameters.xhtml#initiation-peer-up-tlvs>
#[derive(Debug, Eq, PartialEq)]
pub enum InformationTlvType {
String, // type 0
SysDesc, // type 1
SysName, // type 2
VrfTableName, // type 3, RFC 9069
AdminLabel, // type 4, RFC 8671
Undefined(u16),
}
typeenum!(
/// Types of Information TLVs.
///
/// See also
/// <https://www.iana.org/assignments/bmp-parameters/bmp-parameters.xhtml#initiation-peer-up-tlvs>
InformationTlvType, u16,
0 => String,
1 => SysDesc,
2 => SysName,
3 => VrfTableName,
4 => AdminLabel;
5.. => Undefined
);

/// Iterator over `InformationTlv`'s.
pub struct InformationTlvIter<'a> {
Expand Down
89 changes: 58 additions & 31 deletions src/util/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,45 +18,72 @@
/// and `L2Vpn`. On this enum, the [`From`] (for conversion between the
/// variants and `u16`) and [`std::fmt::Display`] traits are implemented.
///
/// You can also specify ranges as like so:
///
/// ```rust
/// typeenum!(

Check failure on line 24 in src/util/macros.rs

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, nightly)

cannot find macro `typeenum` in this scope

Check failure on line 24 in src/util/macros.rs

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, stable)

cannot find macro `typeenum` in this scope

Check failure on line 24 in src/util/macros.rs

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, beta)

cannot find macro `typeenum` in this scope

Check failure on line 24 in src/util/macros.rs

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, nightly)

cannot find macro `typeenum` in this scope

Check failure on line 24 in src/util/macros.rs

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, beta)

cannot find macro `typeenum` in this scope
/// PeerType, u8,
/// 0 => GlobalInstance,
/// 1 => RdInstance,
/// 2 => LocalInstance,
/// 3 => LocalRibInstance;
/// 4..=250 => Unassigned;
/// 251..=254 => Experimental;
/// 255 => Reserved
/// );
/// ```
/// Note that match lines with ranges are separated by semi-colons, rather
/// than by commas. Range variants have a data field with the specified value.
/// Specifying an half-open range to the right or specifying the matches
/// exhaustively will disable the default `Unimplemented` variant.
#[macro_export]
macro_rules! typeenum {
($(#[$attr:meta])* $name:ident, $ty:ty, $($x:expr => $y:ident),+ $(,)*) => {
$(#[$attr])*
#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum $name {
$($y),+,
Unimplemented($ty),
}
($(#[$attr:meta])* $name:ident,
$ty:ty,
$($x:expr => $y:ident),+ $(,)*
$(;$x1:pat => $y1:ident)*) => {
$(#[$attr])*
#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum $name {
$($y),+,
$($y1($ty),)?
Unimplemented($ty),
}

impl From<$ty> for $name {
fn from(f: $ty) -> $name {
match f {
$($x => $name::$y,)+
u => $name::Unimplemented(u),
impl From<$ty> for $name {
#[allow(unreachable_patterns)]
fn from(f: $ty) -> $name {
match f {
$($x => $name::$y,)+
$($x1 => $name::$y1(f),)?
u => $name::Unimplemented(u),
}
}
}
}

impl From<$name> for $ty {
fn from(s: $name) -> $ty {
match s {
$($name::$y => $x,)+
$name::Unimplemented(u) => u,
impl From<$name> for $ty {
fn from(s: $name) -> $ty {
match s {
$($name::$y => $x,)+
$($name::$y1(u) => u,)?
$name::Unimplemented(u) => u,
}
}

}

impl std::fmt::Display for $name {
fn fmt(&self, f: &mut std::fmt::Formatter)
-> Result<(), std::fmt::Error>
{
match self {
$($name::$y => write!(f, stringify!($y))),+,
$($name::$y1(u) => write!(f, "{} ({})", stringify!($u), u),)?
$name::Unimplemented(u) =>
write!(f, "unknown-{}-{}", stringify!($name), u)
}
}
}
}
impl std::fmt::Display for $name {
fn fmt(&self, f: &mut std::fmt::Formatter)
-> Result<(), std::fmt::Error>
{
match self {
$($name::$y => write!(f, stringify!($y))),+,
$name::Unimplemented(u) =>
write!(f, "unknown-{}-{}", stringify!($name), u)
}
}
}
}
}

0 comments on commit 36ce718

Please sign in to comment.