wiredef

6 commits
Updated 2026-04-29 20:05:07
src
src/lib.rs
pub mod msg;
pub mod scalar;
pub mod slice;

#[macro_export]
macro_rules! wiredef {
    (
        $(
            $(#[$meta:meta])*
            $vis:vis struct $name:ident $(<$lt:lifetime>)?: $hsize:ty [$($header:tt)*] {
                $(
                    $(#[$fmeta:meta])*
                    @[$($attrs:tt)*] $fvis:vis $field:ident : $ty:ty
                ),* $(,)?
            }
        )+
    ) => {
        $(
            $(#[$meta])*
            $vis struct $name $(<$lt>)? {
                $(
                    $(#[$fmeta])*
                    $fvis $field: $ty,
                )*
            }

            impl $(<$lt>)? $name $(<$lt>)? {
                $crate::wiredef_header_map!($hsize ; $($header)*);
            }

            impl $(<$lt>)? $crate::msg::WriteMsg for $name $(<$lt>)? {
                fn write_msg_header(&self, buf: &mut &mut [u8]) -> Result<(), $crate::msg::MsgError> {
                    #[allow(unused_mut)]
                    let mut header = Self::BASE;

                    $(
                        $crate::wiredef_header_write!($hsize ; self, buf, header, $field, $ty, [$($attrs)*]);
                    )*

                    $crate::scalar::WriteScalar::write_scalar(&header, buf).map_err($crate::msg::MsgError::Header)?;

                    Ok(())
                }

                fn write_msg_body(&self, #[allow(unused)] buf: &mut &mut [u8]) -> Result<(), $crate::msg::MsgError> {
                    $(
                        $crate::wiredef_body_write!(self, buf, $field, $ty, [$($attrs)*]);
                    )*

                    Ok(())
                }
            }

            impl <'__lt $(, $lt)?> $crate::msg::ReadMsg<'__lt> for $name $(<$lt>)? $(where $lt: '__lt, '__lt: $lt)? {
                type Header = $hsize;

                fn read_msg_header(buf: &mut &'__lt [u8]) -> Result<$hsize, $crate::msg::MsgError> {
                    <$hsize as $crate::scalar::ReadScalar>::read_scalar(buf).map_err($crate::msg::MsgError::Header)
                }

                #[allow(unused)]
                fn read_msg_body(buf: &mut &'__lt [u8], header: $hsize) -> Result<Self, $crate::msg::MsgError> {
                    Ok(Self {
                        $(
                            $field: $crate::wiredef_body_read!(self, buf, header, $field, $ty, [$($attrs)*]),
                        )*
                    })
                }
            }
        )+
    };

    (
        $(#[$meta:meta])*
        $vis:vis struct $name:ident $(<$lt:lifetime>)? {
            $(
                $(#[$fmeta:meta])*
                @[$($attrs:tt)*] $fvis:vis $field:ident : $ty:ty
            ),* $(,)?
        }
    ) => {
        $(#[$meta])*
        $vis struct $name $(<$lt>)? {
            $($(#[$fmeta])*)*
            $($fvis $field: $ty,)*
        }

        impl $(<$lt>)? $crate::msg::WriteMsg for $name $(<$lt>)? {
            fn write_msg_header(&self, _: &mut &mut [u8]) -> Result<(), $crate::msg::MsgError> {
                Ok(())
            }

            fn write_msg_body(&self, buf: &mut &mut [u8]) -> Result<(), $crate::msg::MsgError> {
                $(
                    $crate::wiredef_body_write!(self, buf, $field, $ty, [$($attrs)*]);
                )*

                Ok(())
            }
        }

        impl <'__lt $(, $lt)?> $crate::msg::ReadMsg<'__lt> for $name $(<$lt>)? $(where $lt: '__lt, '__lt: $lt)? {
            type Header = ();

            fn read_msg_header(buf: &mut &'__lt [u8]) -> Result<(), $crate::msg::MsgError> {
                Ok(())
            }

            #[allow(unused)]
            fn read_msg_body(buf: &mut &'__lt [u8], _: ()) -> Result<Self, $crate::msg::MsgError> {
                Ok(Self {
                    $(
                        $field: $crate::wiredef_body_read!(self, buf, (), $field, $ty, [$($attrs)*]),
                    )*
                })
            }
        }
    };
}

wiredef! {
    #[derive(Debug)]
    pub struct Machin<'a>: u16 [Z:7 | M:6 | N:5 | ID:4..1 = 0x1d | W:0 ]  {
        /// test
        @[] pub a: u32,
        @[] pub b: u16,

        /// arstnarst
        @[size=prefixed] pub c: &'a str,

        @[] pub d: u8,
    }
}

#[test]
fn current() {
    use crate::msg::{ReadMsg, WriteMsg};

    let mut buf = [0u8; 32];

    let a = Machin {
        a: 9,
        b: 98,
        c: "Hello, World!",
        d: 244,
    };
    a.write_msg(&mut &mut buf[..]).unwrap();
    println!("{buf:?}");
    let b = Machin::read_msg(&mut &buf[..]);
    println!("{b:?}")
}