1use crate::varint::{
4 varint_max, varint_u16, varint_u32, varint_u64, varint_u128, varint_usize, zig_zag_i16,
5 zig_zag_i32, zig_zag_i64, zig_zag_i128,
6};
7
8#[derive(Debug)]
10pub struct BufferFull;
11
12impl core::fmt::Display for BufferFull {
13 #[inline]
14 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
15 f.write_str("BufferFull")
16 }
17}
18
19pub trait Flavor {
26 type Output;
29
30 type PushError: core::fmt::Debug + core::fmt::Display;
38
39 type FinalizeError: core::fmt::Debug + core::fmt::Display;
45
46 #[inline]
50 fn try_extend(&mut self, data: &[u8]) -> Result<(), Self::PushError> {
51 data.iter().try_for_each(|d| self.try_push(*d))
52 }
53
54 fn try_push(&mut self, data: u8) -> Result<(), Self::PushError>;
56
57 fn finalize(self) -> Result<Self::Output, Self::FinalizeError>;
59}
60
61#[inline]
65pub fn try_push_bool<F: Flavor>(f: &mut F, b: bool) -> Result<(), F::PushError> {
66 let u = if b { 1 } else { 0 };
67 try_push_u8(f, u)
68}
69
70#[inline]
74pub fn try_push_u8<F: Flavor>(f: &mut F, u: u8) -> Result<(), F::PushError> {
75 f.try_push(u)
76}
77
78#[inline]
82pub fn try_push_u16<F: Flavor>(f: &mut F, u: u16) -> Result<(), F::PushError> {
83 let mut buf = [0u8; varint_max::<u16>()];
84 let used_buf = varint_u16(u, &mut buf);
85 f.try_extend(used_buf)
86}
87
88#[inline]
92pub fn try_push_u32<F: Flavor>(f: &mut F, u: u32) -> Result<(), F::PushError> {
93 let mut buf = [0u8; varint_max::<u32>()];
94 let used_buf = varint_u32(u, &mut buf);
95 f.try_extend(used_buf)
96}
97
98#[inline]
102pub fn try_push_u64<F: Flavor>(f: &mut F, u: u64) -> Result<(), F::PushError> {
103 let mut buf = [0u8; varint_max::<u64>()];
104 let used_buf = varint_u64(u, &mut buf);
105 f.try_extend(used_buf)
106}
107
108#[inline]
112pub fn try_push_u128<F: Flavor>(f: &mut F, u: u128) -> Result<(), F::PushError> {
113 let mut buf = [0u8; varint_max::<u128>()];
114 let used_buf = varint_u128(u, &mut buf);
115 f.try_extend(used_buf)
116}
117
118#[inline]
119pub fn try_push_usize<F: Flavor>(f: &mut F, u: usize) -> Result<(), F::PushError> {
120 let mut buf = [0u8; varint_max::<usize>()];
121 let used_buf = varint_usize(u, &mut buf);
122 f.try_extend(used_buf)
123}
124
125#[inline]
129pub fn try_push_i8<F: Flavor>(f: &mut F, i: i8) -> Result<(), F::PushError> {
130 let u = i as u8;
131 f.try_push(u)
132}
133
134#[inline]
138pub fn try_push_i16<F: Flavor>(f: &mut F, i: i16) -> Result<(), F::PushError> {
139 let u = zig_zag_i16(i);
140 try_push_u16(f, u)
141}
142
143#[inline]
147pub fn try_push_i32<F: Flavor>(f: &mut F, i: i32) -> Result<(), F::PushError> {
148 let u = zig_zag_i32(i);
149 try_push_u32(f, u)
150}
151
152#[inline]
156pub fn try_push_i64<F: Flavor>(f: &mut F, i: i64) -> Result<(), F::PushError> {
157 let u = zig_zag_i64(i);
158 try_push_u64(f, u)
159}
160
161#[inline]
165pub fn try_push_i128<F: Flavor>(f: &mut F, i: i128) -> Result<(), F::PushError> {
166 let u = zig_zag_i128(i);
167 try_push_u128(f, u)
168}
169
170#[inline]
171pub fn try_push_isize<F: Flavor>(f: &mut F, i: isize) -> Result<(), F::PushError> {
172 #[cfg(target_pointer_width = "16")]
173 let u = zig_zag_i16(i as i16) as usize;
174 #[cfg(target_pointer_width = "32")]
175 let u = zig_zag_i32(i as i32) as usize;
176 #[cfg(target_pointer_width = "64")]
177 let u = zig_zag_i64(i as i64) as usize;
178
179 try_push_usize(f, u)
180}
181
182#[inline]
186pub fn try_push_f32<F: Flavor>(f: &mut F, fl: f32) -> Result<(), F::PushError> {
187 let u: [u8; 4] = fl.to_bits().to_le_bytes();
188 f.try_extend(&u)
189}
190
191#[inline]
195pub fn try_push_f64<F: Flavor>(f: &mut F, fl: f64) -> Result<(), F::PushError> {
196 let u: [u8; 8] = fl.to_bits().to_le_bytes();
197 f.try_extend(&u)
198}
199
200#[inline]
204pub fn try_push_bytes<F: Flavor>(f: &mut F, b: &[u8]) -> Result<(), F::PushError> {
205 try_push_length(f, b.len())?;
206 f.try_extend(b)
207}
208
209#[inline]
213pub fn try_push_str<F: Flavor>(f: &mut F, b: &str) -> Result<(), F::PushError> {
214 let bytes = b.as_bytes();
215 try_push_bytes(f, bytes)
216}
217
218#[inline]
222pub fn try_push_option_none<F: Flavor>(f: &mut F) -> Result<(), F::PushError> {
223 try_push_u8(f, 0)
224}
225
226#[inline]
230pub fn try_push_option_some<F: Flavor>(f: &mut F) -> Result<(), F::PushError> {
231 try_push_u8(f, 1)
232}
233
234#[inline]
248pub fn try_push_discriminant<F: Flavor>(f: &mut F, v: u32) -> Result<(), F::PushError> {
249 try_push_u32(f, v)
250}
251
252#[inline]
266pub fn try_push_length<F: Flavor>(f: &mut F, v: usize) -> Result<(), F::PushError> {
267 try_push_usize(f, v)
268}
269
270#[inline]
274pub fn try_push_char<F: Flavor>(f: &mut F, v: char) -> Result<(), F::PushError> {
275 let mut buf = [0u8; 4];
276 let strsl = v.encode_utf8(&mut buf);
277 try_push_str(f, strsl)
278}