Skip to content

Commit

Permalink
Constrain T and B generics
Browse files Browse the repository at this point in the history
`Frame` is defined with `T` and `B` generics but the constraints are
only introduced in the impl level which makes it harder to read the enum
and understand whats those generics are about. As those generics are a
key part of the `Frame` enum, it makes more sense to introduce the
constraints in the enum level.
  • Loading branch information
jbesraa committed Jul 8, 2024
1 parent 7836378 commit aaa8f80
Showing 1 changed file with 20 additions and 9 deletions.
29 changes: 20 additions & 9 deletions protocols/v2/framing-sv2/src/framing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ type Slice = buffer_sv2::Slice;
/// A wrapper to be used in a context we need a generic reference to a frame
/// but it doesn't matter which kind of frame it is (`Sv2Frame` or `HandShakeFrame`)
#[derive(Debug)]
pub enum Frame<T, B> {
pub enum Frame<T, B>
where
T: Serialize + GetSize,
B: AsMut<[u8]> + AsRef<[u8]>,
{
HandShake(HandShakeFrame),
Sv2(Sv2Frame<T, B>),
}
Expand All @@ -26,21 +30,25 @@ impl<T: Serialize + GetSize, B: AsMut<[u8]> + AsRef<[u8]>> Frame<T, B> {
}
}

impl<T, B> From<HandShakeFrame> for Frame<T, B> {
impl<T: Serialize + GetSize, B: AsMut<[u8]> + AsRef<[u8]>> From<HandShakeFrame> for Frame<T, B> {
fn from(v: HandShakeFrame) -> Self {
Self::HandShake(v)
}
}

impl<T, B> From<Sv2Frame<T, B>> for Frame<T, B> {
impl<T: Serialize + GetSize, B: AsMut<[u8]> + AsRef<[u8]>> From<Sv2Frame<T, B>> for Frame<T, B> {
fn from(v: Sv2Frame<T, B>) -> Self {
Self::Sv2(v)
}
}

/// Abstraction for a SV2 Frame.
#[derive(Debug, Clone)]
pub enum Sv2Frame<T, B> {
pub enum Sv2Frame<T, B>
where
T: Serialize + GetSize,
B: AsMut<[u8]> + AsRef<[u8]>,
{
Raw(Header, B),
Payload(Header, T),
}
Expand All @@ -52,7 +60,7 @@ impl<T: Serialize + GetSize, B: AsMut<[u8]> + AsRef<[u8]>> Sv2Frame<T, B> {
#[inline]
pub fn serialize(self, dst: &mut [u8]) -> Result<(), Error> {
match self {
Sv2Frame::Raw(header, mut serialized) => {
Sv2Frame::Raw(_, mut serialized) => {
dst.swap_with_slice(serialized.as_mut());
Ok(())
}
Expand Down Expand Up @@ -170,18 +178,21 @@ impl<T: Serialize + GetSize, B: AsMut<[u8]> + AsRef<[u8]>> Sv2Frame<T, B> {
}
}

impl<A, B> Sv2Frame<A, B> {
impl<A: Serialize + GetSize, B: AsMut<[u8]> + AsRef<[u8]>> Sv2Frame<A, B> {
/// Maps a `Sv2Frame<A, B>` to `Sv2Frame<C, B>` by applying `fun`,
/// which is assumed to be a closure that converts `A` to `C`
pub fn map<C>(self, fun: fn(A) -> C) -> Sv2Frame<C, B> {
pub fn map<C>(self, fun: fn(A) -> C) -> Sv2Frame<C, B>
where
C: Serialize + GetSize,
{
match self {
Sv2Frame::Raw(header, serialized) => Sv2Frame::Raw(header, serialized),
Sv2Frame::Payload(header, payload) => Sv2Frame::Payload(header, fun(payload)),
}
}
}

impl<T, B> TryFrom<Frame<T, B>> for Sv2Frame<T, B> {
impl<T: Serialize + GetSize, B: AsMut<[u8]> + AsRef<[u8]>> TryFrom<Frame<T, B>> for Sv2Frame<T, B> {
type Error = Error;

fn try_from(v: Frame<T, B>) -> Result<Self, Error> {
Expand Down Expand Up @@ -223,7 +234,7 @@ impl HandShakeFrame {
}
}

impl<T, B> TryFrom<Frame<T, B>> for HandShakeFrame {
impl<T: Serialize + GetSize, B: AsMut<[u8]> + AsRef<[u8]>> TryFrom<Frame<T, B>> for HandShakeFrame {
type Error = Error;

fn try_from(v: Frame<T, B>) -> Result<Self, Error> {
Expand Down

0 comments on commit aaa8f80

Please sign in to comment.