wire_framed_core/
lib.rs

1pub mod codec;
2pub mod utils;
3pub mod common_impls;
4pub use codec::{FrameCodec, Framed, FramedRead, FramedWrite};
5pub use common_impls::*;
6pub use bytes;
7pub use tokio_util::codec as tokio_codec;
8
9use bytes::{Bytes, BytesMut};
10
11/// Trait for converting a frame into `Self.
12pub trait FromFrame: Sized {
13    /// The error type returned when parsing a frame.
14    type Error;
15
16    /// Parse a frame into a `Self`.
17    fn parse_frame(frame: &mut Bytes) -> Result<Self, Self::Error>;
18
19    /// Convert a frame into a `Self`.
20    fn from_frame(mut frame: Bytes) -> Result<Self, Self::Error> {
21        Self::parse_frame(&mut frame)
22    }
23}
24
25/// Trait for converting a `Self` into a frame.
26pub trait IntoFrame: Sized {
27    /// Extend a frame with the contents of `Self`.
28    fn extend_frame(&self, frame: &mut BytesMut);
29
30    /// Returns the size hint of `Self` in bytes.
31    fn size_hint(&self) -> usize {
32        std::mem::size_of::<Self>()
33    }
34
35    /// Converts `Self` into an owned frame.
36    fn into_frame(&self) -> Bytes {
37        let mut frame = BytesMut::with_capacity(self.size_hint());
38        self.extend_frame(&mut frame);
39        frame.into()
40    }
41}
42
43
44#[cfg(test)]
45mod tests {
46    use bytes::{BufMut, BytesMut};
47    use super::*;
48    
49    struct Test {
50        id: u64,
51        data: Data,
52    }
53
54    struct Data {
55        a: u32,
56        b: u32,
57    }
58
59    #[test]
60    fn from_frame_test() {
61        impl FromFrame for Test {
62            type Error = anyhow::Error;
63
64            fn parse_frame(frame: &mut Bytes) -> Result<Self, Self::Error> {
65                let id = utils::get_u64(frame, "id")?;
66                let data = Data {
67                    a: utils::get_u32(frame, "data.a")?,
68                    b: utils::get_u32(frame, "data.b")?,
69                };
70                
71                Ok(Self {
72                    id,
73                    data,
74                })
75            }
76        }
77
78        let mut frame = BytesMut::new();
79        frame.put_u64(42);
80        frame.put_u32(127);
81        frame.put_u32(72);
82
83        let parsed = Test::from_frame(frame.into()).unwrap();
84        assert_eq!(parsed.id, 42);
85        assert_eq!(parsed.data.a, 127);
86        assert_eq!(parsed.data.b, 72);
87    }
88    
89    #[test]
90    fn into_frame_test() {
91        impl IntoFrame for Test {
92            fn extend_frame(&self, frame: &mut BytesMut) {
93                frame.put_u64(self.id);
94                frame.put_u32(self.data.a);
95                frame.put_u32(self.data.b);
96            }
97        }
98
99        let test = Test { id: 42, data: Data { a: 127, b: 72 } };
100        let result = test.into_frame();
101
102        let target = Bytes::from_static(&[
103            0, 0, 0, 0, 0, 0, 0, 42,
104            0, 0, 0, 127,
105            0, 0, 0, 72,
106        ]);
107        assert_eq!(&result, &target);
108    }
109}