1pub use compactly_derive::EncodeV1 as Encode;
7use std::io::{Read, Write};
8
9mod adapt;
10mod arc;
11mod arith;
12mod array;
13mod bit_context;
14mod bits;
15mod bools;
16mod byte;
17mod bytes;
18mod floats;
19#[cfg(feature = "generate_bit_context")]
20pub mod generate_bit_context;
21mod ints;
22mod low_cardinality;
23mod maps;
24mod option;
25mod sets;
26mod string;
27mod tuples;
28mod ulessthan;
29mod usizes;
30mod vecs;
31
32use crate::{LowCardinality, Small};
33pub use adapt::{Reader, Writer};
34pub use ulessthan::ULessThan;
35
36pub trait Encode: Sized {
41 type Context: Default + Clone;
43
44 fn encode<W: Write>(
46 &self,
47 writer: &mut Writer<W>,
48 ctx: &mut Self::Context,
49 ) -> Result<(), std::io::Error>;
50
51 #[expect(unused_variables)]
55 fn millibits(&self, ctx: &mut Self::Context) -> Option<usize> {
56 None
60 }
61
62 fn decode<R: Read>(
64 reader: &mut Reader<R>,
65 ctx: &mut Self::Context,
66 ) -> Result<Self, std::io::Error>;
67}
68
69pub fn encode<T: Encode>(value: &T) -> Vec<u8> {
71 let mut out = Vec::with_capacity(8);
72 {
73 let mut writer = Writer::new(&mut out);
74 value
75 .encode(&mut writer, &mut T::Context::default())
76 .unwrap();
77 writer.finish().unwrap();
78 }
79 out
80}
81
82pub fn decode<T: Encode>(mut bytes: &[u8]) -> Option<T> {
86 let mut reader = Reader::new(&mut bytes).unwrap();
87 T::decode(&mut reader, &mut T::Context::default()).ok()
88}
89
90pub trait EncodingStrategy<T>: Copy {
102 type Context: Default + Clone;
104
105 fn encode<W: Write>(
107 value: &T,
108 writer: &mut Writer<W>,
109 ctx: &mut Self::Context,
110 ) -> Result<(), std::io::Error>;
111
112 #[expect(unused_variables)]
114 fn millibits(value: &T, ctx: &mut Self::Context) -> Option<usize> {
115 None
116 }
117
118 fn decode<R: Read>(
120 reader: &mut Reader<R>,
121 ctx: &mut Self::Context,
122 ) -> Result<T, std::io::Error>;
123}
124
125pub fn encode_with<T: Encode, S: EncodingStrategy<T>>(_: S, value: &T) -> Vec<u8> {
130 let mut out = Vec::with_capacity(8);
131 {
132 let mut writer = Writer::<&mut Vec<u8>>::new(&mut out);
133 S::encode(value, &mut writer, &mut S::Context::default()).unwrap();
134 writer.finish().unwrap();
135 }
136 out
137}
138
139pub fn decode_with<T: Encode, S: EncodingStrategy<T>>(_: S, mut bytes: &[u8]) -> Option<T> {
144 let mut reader = Reader::new(&mut bytes).unwrap();
145 S::decode(&mut reader, &mut S::Context::default()).ok()
146}
147
148impl<T, S: EncodingStrategy<T>> Encode for crate::Encoded<T, S> {
149 type Context = S::Context;
150 #[inline]
151 fn encode<W: std::io::Write>(
152 &self,
153 writer: &mut Writer<W>,
154 ctx: &mut Self::Context,
155 ) -> Result<(), std::io::Error> {
156 S::encode(&self.value, writer, ctx)
157 }
158 #[inline]
159 fn millibits(&self, ctx: &mut Self::Context) -> Option<usize> {
160 S::millibits(&self.value, ctx)
161 }
162 #[inline]
163 fn decode<R: std::io::Read>(
164 reader: &mut Reader<R>,
165 ctx: &mut Self::Context,
166 ) -> Result<Self, std::io::Error> {
167 Ok(Self {
168 value: S::decode(reader, ctx)?,
169 _phantom: std::marker::PhantomData,
170 })
171 }
172}
173
174impl<T: Encode> EncodingStrategy<T> for crate::Normal {
175 type Context = <T as Encode>::Context;
176 #[inline]
177 fn encode<W: Write>(
178 value: &T,
179 writer: &mut Writer<W>,
180 ctx: &mut Self::Context,
181 ) -> Result<(), std::io::Error> {
182 value.encode(writer, ctx)
183 }
184 fn millibits(value: &T, ctx: &mut Self::Context) -> Option<usize> {
185 value.millibits(ctx)
186 }
187 fn decode<R: Read>(
188 reader: &mut Reader<R>,
189 ctx: &mut Self::Context,
190 ) -> Result<T, std::io::Error> {
191 T::decode(reader, ctx)
192 }
193}
194
195#[cfg(test)]
196macro_rules! assert_size {
197 ($v:expr, $size:expr) => {
198 let v = $v;
199 let bytes = super::encode(&v);
200 let decoded = super::decode(&bytes);
201 assert_eq!(decoded, Some(v), "decoded value is incorrect");
202 assert_eq!(bytes.len(), $size, "unexpected size");
203 };
204}
205#[cfg(test)]
206pub(crate) use assert_size;
207
208#[cfg(test)]
209macro_rules! assert_bits {
210 ($v:expr, $size:expr) => {
211 let v1 = $v;
212 let bytes = super::encode(&v1);
213 let decoded = super::decode(&bytes);
214 assert_eq!(decoded, Some(v1), "decoded value is incorrect");
215 let v = (
216 ($v, $v, $v, $v, $v, $v, $v, $v),
217 ($v, $v, $v, $v, $v, $v, $v, $v),
218 ($v, $v, $v, $v, $v, $v, $v, $v),
219 ($v, $v, $v, $v, $v, $v, $v, $v),
220 ($v, $v, $v, $v, $v, $v, $v, $v),
221 ($v, $v, $v, $v, $v, $v, $v, $v),
222 ($v, $v, $v, $v, $v, $v, $v, $v),
223 ($v, $v, $v, $v, $v, $v, $v, $v),
224 );
225 let bytes = super::encode(&v);
226 let decoded = super::decode(&bytes);
227 assert_eq!(decoded, Some(v), "decoded tuple value is incorrect");
228 assert_eq!((bytes.len() + 4) / 8, $size, "unexpected number of bits");
229 };
230 ($v:expr, $size:expr, $msg:expr) => {
231 let v1 = $v;
232 let bytes = super::encode(&v1);
233 let decoded = super::decode(&bytes);
234 assert_eq!(decoded, Some(v1), "decoded value is incorrect: {}", $msg);
235 let v = (
236 ($v, $v, $v, $v, $v, $v, $v, $v),
237 ($v, $v, $v, $v, $v, $v, $v, $v),
238 ($v, $v, $v, $v, $v, $v, $v, $v),
239 ($v, $v, $v, $v, $v, $v, $v, $v),
240 ($v, $v, $v, $v, $v, $v, $v, $v),
241 ($v, $v, $v, $v, $v, $v, $v, $v),
242 ($v, $v, $v, $v, $v, $v, $v, $v),
243 ($v, $v, $v, $v, $v, $v, $v, $v),
244 );
245 let bytes = super::encode(&v);
246 let decoded = super::decode(&bytes);
247 assert_eq!(
248 decoded,
249 Some(v),
250 "decoded tuple value is incorrect: {}",
251 $msg
252 );
253 assert_eq!(
254 (bytes.len() + 4) / 8,
255 $size,
256 "unexpected number of bits: {}",
257 $msg
258 );
259 };
260}
261#[cfg(test)]
262pub(crate) use assert_bits;