1pub use bincode::{Error, ErrorKind, Options, Result};
2
3mod options {
5 use bincode::config::{
6 AllowTrailing, BigEndian, Bounded, DefaultOptions as BincodeDefaultOptions, FixintEncoding,
7 Options as _, WithOtherEndian, WithOtherIntEncoding, WithOtherLimit, WithOtherTrailing,
8 };
9
10 pub type Default =
11 WithOtherIntEncoding<WithOtherEndian<BincodeDefaultOptions, BigEndian>, FixintEncoding>;
12
13 #[inline]
14 pub fn default() -> Default {
15 bincode::options().with_big_endian().with_fixint_encoding()
16 }
17
18 pub type SP1Compatible = WithOtherTrailing<
19 WithOtherIntEncoding<BincodeDefaultOptions, FixintEncoding>,
20 AllowTrailing,
21 >;
22
23 #[inline]
24 pub fn sp1_compatible() -> SP1Compatible {
25 bincode::options()
26 .with_fixint_encoding()
27 .allow_trailing_bytes()
28 }
29
30 pub type Limited<T> = WithOtherLimit<T, Bounded>;
31}
32
33#[derive(Clone, Debug)]
35pub struct Codec<Opts>(Opts);
36
37#[inline]
39pub fn default() -> Codec<options::Default> {
40 Codec(options::default())
41}
42
43#[inline]
45pub fn sp1_compatible() -> Codec<options::SP1Compatible> {
46 Codec(options::sp1_compatible())
47}
48
49#[deprecated(note = "use sp1_compatible()")]
51#[inline]
52pub fn sp1v4() -> Codec<options::SP1Compatible> {
53 sp1_compatible()
54}
55
56#[inline]
60pub fn contracts() -> Codec<options::Default> {
61 default()
62}
63
64impl<Opts: Options> Codec<Opts> {
65 #[inline]
67 pub fn with_limit(self, max: u64) -> Codec<options::Limited<Opts>> {
68 Codec(self.0.with_limit(max))
69 }
70
71 #[inline]
73 pub fn serialize<T>(self, item: &T) -> Result<Vec<u8>>
74 where
75 T: ?Sized + serde::Serialize,
76 {
77 self.0.serialize(item)
78 }
79
80 #[inline]
82 pub fn serialize_into<W, T>(self, writer: W, item: &T) -> Result<()>
83 where
84 W: std::io::Write,
85 T: ?Sized + serde::Serialize,
86 {
87 self.0.serialize_into(writer, item)
88 }
89
90 #[inline]
92 pub fn deserialize<'a, T>(self, bytes: &'a [u8]) -> Result<T>
93 where
94 T: serde::Deserialize<'a>,
95 {
96 self.0.deserialize(bytes)
97 }
98
99 #[inline]
101 pub fn deserialize_from<T, R>(self, reader: R) -> Result<T>
102 where
103 T: serde::de::DeserializeOwned,
104 R: std::io::Read,
105 {
106 self.0.deserialize_from(reader)
107 }
108}
109
110#[cfg(test)]
111mod test {
112 #[test]
113 fn sp1_endians() {
114 type NetworkId = u32;
115
116 let network_id: NetworkId = 0x00112233;
117 let network_id_enc = super::sp1_compatible().serialize(&network_id).unwrap();
118
119 let mut stdin0 = sp1_sdk::SP1Stdin::new();
120 stdin0.write_slice(&network_id_enc);
121
122 let mut stdin1 = sp1_sdk::SP1Stdin::new();
123 stdin1.write(&network_id);
124
125 assert_eq!(&stdin1.buffer[0], &[0x33, 0x22, 0x11, 0x00]);
126 assert_eq!(stdin0.buffer, stdin1.buffer);
127 assert_eq!(stdin0.read::<NetworkId>(), stdin1.read::<NetworkId>());
128 }
129
130 #[test]
131 fn sp1_compatible_round_trips_network_id() {
132 type NetworkId = u32;
133
134 let bytes = vec![0x33, 0x22, 0x11, 0x00];
135
136 let decoded: NetworkId = super::sp1_compatible().deserialize(&bytes).unwrap();
137
138 assert_eq!(decoded, 0x00112233);
139 }
140}