Skip to content

Commit

Permalink
refactor: macro to simplify enums for encoded types
Browse files Browse the repository at this point in the history
  • Loading branch information
mlegner committed Dec 14, 2023
1 parent 35daeea commit f0ab60d
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 44 deletions.
1 change: 1 addition & 0 deletions crates/scion-proto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub mod datagram;
pub mod packet;
pub mod path;
pub mod reliable;
pub(crate) mod utils;
pub mod wire_encoding;

#[cfg(test)]
Expand Down
62 changes: 18 additions & 44 deletions crates/scion-proto/src/path/dataplane.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,53 +5,27 @@ use bytes::{Buf, BufMut, Bytes};
use crate::{
packet::{DecodeError, InadequateBufferSize},
path::standard::StandardPath,
utils::encoded_type,
wire_encoding::{WireDecode, WireDecodeWithContext, WireEncode},
};

/// SCION path types that may be encountered in a packet.
#[repr(u8)]
#[non_exhaustive]
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum PathType {
/// The empty path type.
Empty,
/// The standard SCION path type.
Scion,
/// One-hop paths between neighboring border routers.
OneHop,
/// Experimental Epic path type.
Epic,
/// Experimental Colibri path type.
Colibri,
/// Other, unrecognized path types.
Other(u8),
}

impl From<PathType> for u8 {
fn from(value: PathType) -> Self {
match value {
PathType::Empty => 0,
PathType::Scion => 1,
PathType::OneHop => 2,
PathType::Epic => 3,
PathType::Colibri => 4,
PathType::Other(value) => value,
}
}
}

impl From<u8> for PathType {
fn from(value: u8) -> Self {
match value {
0 => Self::Empty,
1 => Self::Scion,
2 => Self::OneHop,
3 => Self::Epic,
4 => Self::Colibri,
value => Self::Other(value),
}
}
}
encoded_type!(
/// SCION path types that may be encountered in a packet.
pub enum PathType(u8){
/// The empty path type.
Empty = 0,
/// The standard SCION path type.
Scion = 1,
/// One-hop paths between neighboring border routers.
OneHop = 2,
/// Experimental Epic path type.
Epic = 3,
/// Experimental Colibri path type.
Colibri = 4;
/// Other, unrecognized path types.
Other = _,
}
);

/// Error returned when performing operations on a path of currently unsupported [`PathType`].
#[derive(Debug, thiserror::Error)]
Expand Down
43 changes: 43 additions & 0 deletions crates/scion-proto/src/utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//! Utils used internally in other modules.

/// This macro helps with creating enum types for some attributes that are encoded as short integer
/// values like [`u8`]. It generates bidirectional [`From`] implementations for the representation
/// type and supports catch-all/other variants.
macro_rules! encoded_type {
(
$(#[$outer:meta])*
pub enum $name:ident ($representation_type:ty) {
$($(#[$doc:meta])* $variant:ident = $value:literal),*;
$($(#[$doc_other:meta])* $variant_other:ident = $range:pat,)*
}
) => {
$(#[$outer])*
#[repr($representation_type)]
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum $name {
$($(#[$doc])* $variant = $value,)*
$($(#[$doc_other])* $variant_other($representation_type),)*
}

impl From<$representation_type> for $name {
fn from(value: $representation_type) -> Self {
match value {
$($value => Self::$variant,)*
#[allow(clippy::redundant_pattern)]
$(x@$range => Self::$variant_other(x),)*
}
}
}

impl From<$name> for $representation_type {
fn from(value: $name) -> Self {
match value {
$($name::$variant => $value,)*
$($name::$variant_other(x) => x,)*
}
}
}
};
}
pub(crate) use encoded_type;

0 comments on commit f0ab60d

Please sign in to comment.