1#[cfg(feature = "async")]
2pub mod async_read_write;
3#[cfg(feature = "async")]
4mod async_traits;
5
6extern crate binprot_derive;
7pub mod macros {
8 pub use binprot_derive::*;
9}
10
11#[doc(hidden)]
13pub use ::byteorder;
14
15mod error;
16mod int;
17mod shape;
18mod traits;
19
20pub use crate::error::Error;
21pub use crate::shape::{Digestible, Shape};
22pub use crate::traits::{BinProtRead, BinProtShape, BinProtSize, BinProtWrite, ShapeContext};
23
24use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
25use std::convert::TryFrom;
26use std::hash::Hash;
27use std::io::{Read, Write};
28
29pub fn binprot_write_with_size<W: Write, B: BinProtWrite>(b: &B, w: &mut W) -> std::io::Result<()> {
32 let len = b.binprot_size();
33 w.write_i64::<byteorder::LittleEndian>(len as i64)?;
34 b.binprot_write(w)
35}
36
37pub fn binprot_read_with_size<R: Read, B: BinProtRead>(r: &mut R) -> Result<B, Error> {
39 let _len = r.read_i64::<byteorder::LittleEndian>()?;
41 B::binprot_read(r)
42}
43
44#[derive(Debug, Clone, PartialEq, Eq, Copy)]
45pub struct Nat0(pub u64);
46
47#[derive(Debug, Clone, PartialEq, Eq)]
48pub struct Bytes(pub Vec<u8>);
49
50impl std::convert::From<String> for Bytes {
51 fn from(str: String) -> Self {
52 Bytes(str.into_bytes())
53 }
54}
55
56impl std::convert::From<&str> for Bytes {
57 fn from(str: &str) -> Self {
58 Bytes(str.as_bytes().to_vec())
59 }
60}
61
62impl std::convert::From<Vec<u8>> for Bytes {
63 fn from(v: Vec<u8>) -> Self {
64 Bytes(v)
65 }
66}
67
68impl BinProtWrite for Nat0 {
69 fn binprot_write<W: Write>(&self, w: &mut W) -> std::io::Result<()> {
70 int::write_nat0(w, self.0)
71 }
72}
73
74impl BinProtWrite for i64 {
75 fn binprot_write<W: Write>(&self, w: &mut W) -> std::io::Result<()> {
76 int::write_i64(w, *self as i64)
77 }
78}
79
80impl BinProtWrite for f64 {
81 fn binprot_write<W: Write>(&self, w: &mut W) -> std::io::Result<()> {
82 w.write_all(&self.to_le_bytes())
83 }
84}
85
86impl BinProtWrite for () {
87 fn binprot_write<W: Write>(&self, w: &mut W) -> std::io::Result<()> {
88 w.write_all(&[0u8])
89 }
90}
91
92impl BinProtWrite for bool {
93 fn binprot_write<W: Write>(&self, w: &mut W) -> std::io::Result<()> {
94 let b = if *self { 1 } else { 0 };
95 w.write_all(&[b])
96 }
97}
98
99impl<T: BinProtWrite> BinProtWrite for Option<T> {
100 fn binprot_write<W: Write>(&self, w: &mut W) -> std::io::Result<()> {
101 match &*self {
102 None => w.write_all(&[0u8]),
103 Some(v) => {
104 w.write_all(&[1u8])?;
105 v.binprot_write(w)
106 }
107 }
108 }
109}
110
111impl<T: BinProtWrite> BinProtWrite for Box<T> {
112 fn binprot_write<W: Write>(&self, w: &mut W) -> std::io::Result<()> {
113 self.as_ref().binprot_write(w)
114 }
115}
116
117impl<T: BinProtWrite> BinProtWrite for Vec<T> {
118 fn binprot_write<W: Write>(&self, w: &mut W) -> std::io::Result<()> {
119 int::write_nat0(w, self.len() as u64)?;
120 for v in self.iter() {
121 v.binprot_write(w)?
122 }
123 Ok(())
124 }
125}
126
127impl BinProtWrite for Vec<f32> {
131 fn binprot_write<W: Write>(&self, w: &mut W) -> std::io::Result<()> {
132 int::write_nat0(w, self.len() as u64)?;
133 for v in self.iter() {
134 w.write_f32::<byteorder::NativeEndian>(*v)?
135 }
136 Ok(())
137 }
138}
139
140impl<T: BinProtWrite> BinProtWrite for &[T] {
141 fn binprot_write<W: Write>(&self, w: &mut W) -> std::io::Result<()> {
142 int::write_nat0(w, self.len() as u64)?;
143 for v in self.iter() {
144 v.binprot_write(w)?
145 }
146 Ok(())
147 }
148}
149
150impl BinProtWrite for String {
151 fn binprot_write<W: Write>(&self, w: &mut W) -> std::io::Result<()> {
152 let bytes = self.as_bytes();
153 int::write_nat0(w, bytes.len() as u64)?;
154 w.write_all(bytes)
155 }
156}
157
158impl BinProtWrite for &str {
159 fn binprot_write<W: Write>(&self, w: &mut W) -> std::io::Result<()> {
160 let bytes = self.as_bytes();
161 int::write_nat0(w, bytes.len() as u64)?;
162 w.write_all(bytes)
163 }
164}
165
166impl BinProtWrite for Bytes {
167 fn binprot_write<W: Write>(&self, w: &mut W) -> std::io::Result<()> {
168 let bytes = &self.0;
169 int::write_nat0(w, bytes.len() as u64)?;
170 w.write_all(bytes)
171 }
172}
173
174impl<K: BinProtWrite, V: BinProtWrite> BinProtWrite for std::collections::BTreeMap<K, V> {
175 fn binprot_write<W: Write>(&self, w: &mut W) -> std::io::Result<()> {
177 int::write_nat0(w, self.len() as u64)?;
178 for (k, v) in self.iter() {
179 k.binprot_write(w)?;
180 v.binprot_write(w)?;
181 }
182 Ok(())
183 }
184}
185
186impl<K: BinProtWrite, V: BinProtWrite> BinProtWrite for std::collections::HashMap<K, V> {
187 fn binprot_write<W: Write>(&self, w: &mut W) -> std::io::Result<()> {
189 int::write_nat0(w, self.len() as u64)?;
190 for (k, v) in self.iter() {
191 k.binprot_write(w)?;
192 v.binprot_write(w)?;
193 }
194 Ok(())
195 }
196}
197
198macro_rules! tuple_impls {
199 ( $( $name:ident )+ ) => {
200 impl<$($name: BinProtWrite),+> BinProtWrite for ($($name,)+)
201 {
202 #[allow(non_snake_case)]
203 fn binprot_write<W: Write>(&self, w: &mut W) -> std::io::Result<()> {
204 let ($($name,)+) = self;
205 $($name.binprot_write(w)?;)+
206 Ok(())
207 }
208 }
209
210 impl<$($name: BinProtRead),+> BinProtRead for ($($name,)+)
211 {
212 #[allow(non_snake_case)]
213 fn binprot_read<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error>
214 where
215 Self: Sized,
216 {
217 $(let $name = $name::binprot_read(r)?;)+
218 Ok(($($name,)+))
219 }
220 }
221
222 impl<$($name: BinProtShape),+> BinProtShape for ($($name,)+)
223 {
224 #[allow(non_snake_case)]
225 fn binprot_shape_impl(ctxt: &mut ShapeContext) -> Shape
226 {
227 $(let $name = <$name>::binprot_shape_loop(ctxt);)+
228 Shape::Tuple(vec![$($name,)+])
229 }
230 }
231 };
232}
233
234tuple_impls! { A }
235tuple_impls! { A B }
236tuple_impls! { A B C }
237tuple_impls! { A B C D }
238tuple_impls! { A B C D E }
239tuple_impls! { A B C D E F }
240tuple_impls! { A B C D E F G }
241tuple_impls! { A B C D E F G H }
242tuple_impls! { A B C D E F G H I }
243
244impl BinProtRead for Nat0 {
245 fn binprot_read<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error>
246 where
247 Self: Sized,
248 {
249 let u64 = int::read_nat0(r)?;
250 Ok(Nat0(u64))
251 }
252}
253
254impl BinProtRead for i64 {
255 fn binprot_read<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error>
256 where
257 Self: Sized,
258 {
259 let i64 = int::read_signed(r)?;
260 Ok(i64)
261 }
262}
263
264impl BinProtRead for f64 {
265 fn binprot_read<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error>
266 where
267 Self: Sized,
268 {
269 let f64 = r.read_f64::<LittleEndian>()?;
270 Ok(f64)
271 }
272}
273
274impl BinProtRead for () {
275 fn binprot_read<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error>
276 where
277 Self: Sized,
278 {
279 let c = r.read_u8()?;
280 if c == 0 {
281 Ok(())
282 } else {
283 Err(Error::UnexpectedValueForUnit(c))
284 }
285 }
286}
287
288impl BinProtRead for bool {
289 fn binprot_read<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error>
290 where
291 Self: Sized,
292 {
293 let c = r.read_u8()?;
294 if c == 0 {
295 Ok(false)
296 } else if c == 1 {
297 Ok(true)
298 } else {
299 Err(Error::UnexpectedValueForBool(c))
300 }
301 }
302}
303
304impl<T: BinProtRead> BinProtRead for Option<T> {
305 fn binprot_read<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error>
306 where
307 Self: Sized,
308 {
309 let c = r.read_u8()?;
310 if c == 0 {
311 Ok(None)
312 } else if c == 1 {
313 let v = T::binprot_read(r)?;
314 Ok(Some(v))
315 } else {
316 Err(Error::UnexpectedValueForOption(c))
317 }
318 }
319}
320
321impl<T: BinProtRead> BinProtRead for Box<T> {
322 fn binprot_read<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error>
323 where
324 Self: Sized,
325 {
326 let v = T::binprot_read(r)?;
327 Ok(Box::new(v))
328 }
329}
330
331impl<T: BinProtRead> BinProtRead for Vec<T> {
332 fn binprot_read<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error>
333 where
334 Self: Sized,
335 {
336 let len = int::read_nat0(r)?;
337 let mut v: Vec<T> = Vec::new();
338 for _i in 0..len {
339 let item = T::binprot_read(r)?;
340 v.push(item)
341 }
342 Ok(v)
343 }
344}
345
346impl BinProtRead for Vec<f32> {
350 fn binprot_read<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error>
351 where
352 Self: Sized,
353 {
354 let len = int::read_nat0(r)?;
355 let mut v: Vec<f32> = Vec::new();
356 for _i in 0..len {
357 let item = r.read_f32::<byteorder::NativeEndian>()?;
358 v.push(item)
359 }
360 Ok(v)
361 }
362}
363
364impl<K: BinProtRead + Ord, V: BinProtRead> BinProtRead for std::collections::BTreeMap<K, V> {
365 fn binprot_read<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error>
366 where
367 Self: Sized,
368 {
369 let len = int::read_nat0(r)?;
370 let mut res = std::collections::BTreeMap::new();
371 for _i in 0..len {
372 let k = K::binprot_read(r)?;
373 let v = V::binprot_read(r)?;
374 if res.insert(k, v).is_some() {
375 return Err(Error::SameKeyAppearsTwiceInMap);
376 }
377 }
378 Ok(res)
379 }
380}
381
382impl<K: BinProtRead + Hash + Eq, V: BinProtRead> BinProtRead for std::collections::HashMap<K, V> {
383 fn binprot_read<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error>
384 where
385 Self: Sized,
386 {
387 let len = int::read_nat0(r)?;
388 let mut res = std::collections::HashMap::new();
389 for _i in 0..len {
390 let k = K::binprot_read(r)?;
391 let v = V::binprot_read(r)?;
392 if res.insert(k, v).is_some() {
393 return Err(Error::SameKeyAppearsTwiceInMap);
394 }
395 }
396 Ok(res)
397 }
398}
399
400impl BinProtRead for String {
401 fn binprot_read<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error>
402 where
403 Self: Sized,
404 {
405 let len = int::read_nat0(r)?;
406 let mut buf: Vec<u8> = vec![0u8; len as usize];
407 r.read_exact(&mut buf)?;
408 let str = std::str::from_utf8(&buf)?;
409 Ok(str.to_string())
410 }
411}
412
413impl BinProtRead for Bytes {
414 fn binprot_read<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error>
415 where
416 Self: Sized,
417 {
418 let len = int::read_nat0(r)?;
419 let mut buf: Vec<u8> = vec![0u8; len as usize];
420 r.read_exact(&mut buf)?;
421 Ok(Bytes(buf))
422 }
423}
424
425#[derive(Debug, Clone, PartialEq, Eq)]
428pub struct WithLen<T>(pub T);
429
430impl<T: BinProtWrite + BinProtSize> BinProtWrite for WithLen<T> {
431 fn binprot_write<W: Write>(&self, w: &mut W) -> std::io::Result<()> {
432 let len = self.0.binprot_size();
433 int::write_nat0(w, len as u64)?;
434 self.0.binprot_write(w)
435 }
436}
437
438impl<T: BinProtRead> BinProtRead for WithLen<T> {
439 fn binprot_read<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error>
440 where
441 Self: Sized,
442 {
443 let _len = int::read_nat0(r)?;
445 let t = T::binprot_read(r)?;
446 Ok(WithLen(t))
447 }
448}
449
450#[derive(Debug, Clone, PartialEq)]
452pub struct BufferWithLen(pub Vec<u8>);
453
454impl BinProtRead for BufferWithLen {
455 fn binprot_read<R: std::io::Read + ?Sized>(r: &mut R) -> Result<Self, Error>
456 where
457 Self: Sized,
458 {
459 let len = Nat0::binprot_read(r)?;
460 let mut buf: Vec<u8> = vec![0u8; len.0 as usize];
461 r.read_exact(&mut buf)?;
462 Ok(BufferWithLen(buf))
463 }
464}
465
466impl BinProtWrite for BufferWithLen {
467 fn binprot_write<W: std::io::Write>(&self, w: &mut W) -> Result<(), std::io::Error> {
468 let nat0 = Nat0(self.0.len() as u64);
469 nat0.binprot_write(w)?;
470 w.write_all(&self.0)?;
471 Ok(())
472 }
473}
474
475macro_rules! int_impls {
479 ( $ty: ty) => {
480 impl BinProtWrite for $ty {
481 fn binprot_write<W: Write>(&self, w: &mut W) -> std::io::Result<()> {
482 int::write_i64(w, (*self).into())
483 }
484 }
485
486 impl BinProtRead for $ty {
487 fn binprot_read<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error>
488 where
489 Self: Sized,
490 {
491 let i64 = int::read_signed(r)?;
492 Ok(<$ty>::try_from(i64)?)
493 }
494 }
495 };
496}
497
498int_impls!(i32);
499int_impls!(u32);
500int_impls!(i16);
501int_impls!(u16);
502int_impls!(i8);
503int_impls!(u8);