solana_fixed_buf/
lib.rs

1//! ser- and deser-ialize-able, fixed-size bufs
2
3#[macro_export]
4macro_rules! fixed_buf {
5    ($name:ident, $size:expr) => {
6        fixed_buf!($name, $size, 12);
7    };
8    ($name:ident, $size:expr, $max_print: expr) => {
9        pub struct $name {
10            _inner: [u8; $size],
11        }
12
13        impl Default for $name {
14            fn default() -> Self {
15                $name { _inner: [0; $size] }
16            }
17        }
18
19        impl PartialEq for $name {
20            fn eq(&self, other: &Self) -> bool {
21                self.iter().zip(other.iter()).all(|(me, other)| me == other)
22            }
23        }
24        impl Eq for $name {}
25
26        impl std::ops::Deref for $name {
27            type Target = [u8; $size];
28            fn deref(&self) -> &Self::Target {
29                &self._inner
30            }
31        }
32
33        impl std::ops::DerefMut for $name {
34            fn deref_mut(&mut self) -> &mut Self::Target {
35                &mut self._inner
36            }
37        }
38
39        impl std::fmt::Debug for $name {
40            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41                write!(f, "[{}", self[0])?;
42                for i in 1..self.len().min($max_print) {
43                    write!(f, ", {}", self[i])?;
44                }
45                if $max_print < self.len() {
46                    write!(f, ", ...")?;
47                }
48                write!(f, "]")
49            }
50        }
51
52        impl<'de> serde::Deserialize<'de> for $name {
53            fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
54            where
55                D: serde::Deserializer<'de>,
56            {
57                struct Visitor;
58                impl<'de> serde::de::Visitor<'de> for Visitor {
59                    type Value = $name;
60
61                    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
62                        formatter.write_str(stringify!($name))
63                    }
64                    fn visit_bytes<E>(self, bytes: &[u8]) -> Result<Self::Value, E>
65                    where
66                        E: serde::de::Error,
67                    {
68                        if bytes.len() != $size {
69                            Err(serde::de::Error::invalid_length(
70                                bytes.len(),
71                                &stringify!($size),
72                            ))?
73                        }
74                        let mut buf = $name::default();
75                        buf.copy_from_slice(bytes);
76
77                        Ok(buf)
78                    }
79                }
80                deserializer.deserialize_bytes(Visitor)
81            }
82        }
83
84        impl serde::ser::Serialize for $name {
85            fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
86            where
87                S: serde::ser::Serializer,
88            {
89                serializer.serialize_bytes(&self._inner)
90            }
91        }
92    };
93}
94
95#[cfg(test)]
96mod test {
97    use serde_derive::{Deserialize, Serialize};
98
99    fixed_buf!(BufMath, 33);
100
101    #[derive(Debug, Default, Serialize, Deserialize, PartialEq, Eq)]
102    pub struct Foo {
103        pub foo: u64,
104        pub buf: BufMath,
105    }
106
107    fixed_buf!(Buf34, 34, 35); // print even more than is present!
108
109    #[derive(Debug, Default, Serialize, Deserialize, PartialEq, Eq)]
110    pub struct Foo34 {
111        pub foo: u64,
112        pub buf: Buf34,
113    }
114
115    #[test]
116    fn test() {
117        let mut foo = Foo {
118            foo: 33,
119            ..Foo::default()
120        };
121        foo.buf[1] = 127;
122        let ser = bincode::serialize(&foo).unwrap();
123        assert_eq!(bincode::deserialize::<Foo>(&ser).unwrap(), foo);
124
125        assert_eq!(
126            format!("{:?}", foo),
127            "Foo { foo: 33, buf: [0, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...] }"
128        );
129
130        let mut foo = Foo34 {
131            foo: 34,
132            ..Foo34::default()
133        };
134        foo.buf[1] = 128;
135        let ser = bincode::serialize(&foo).unwrap();
136        assert_eq!(bincode::deserialize::<Foo34>(&ser).unwrap(), foo);
137
138        assert!(bincode::deserialize::<Foo>(&ser).is_err());
139
140        assert_eq!(format!("{:?}", foo), "Foo34 { foo: 34, buf: [0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }");
141    }
142}