1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![doc = include_str!("../README.md")]
3#![deny(missing_docs)]
4#![cfg_attr(not(feature = "std"), no_std)]
5
6use core::fmt::Debug;
7#[allow(unused_imports)]
8use std_shims::prelude::*;
9use std_shims::io::{self, Read, Write};
10
11mod varint;
12pub use varint::*;
13
14pub fn write_byte<W: Write>(byte: &u8, w: &mut W) -> io::Result<()> {
18 w.write_all(&[*byte])
19}
20
21pub fn write_raw_vec<T, W: Write, F: FnMut(&T, &mut W) -> io::Result<()>>(
23 mut f: F,
24 values: &[T],
25 w: &mut W,
26) -> io::Result<()> {
27 for value in values {
28 f(value, w)?;
29 }
30 Ok(())
31}
32
33pub fn write_vec<T, W: Write, F: FnMut(&T, &mut W) -> io::Result<()>>(
35 f: F,
36 values: &[T],
37 w: &mut W,
38) -> io::Result<()> {
39 VarInt::write(&values.len(), w)?;
40 write_raw_vec(f, values, w)
41}
42
43pub fn read_bytes<R: Read, const N: usize>(r: &mut R) -> io::Result<[u8; N]> {
45 let mut res = [0; N];
46 r.read_exact(&mut res)?;
47 Ok(res)
48}
49
50pub fn read_byte<R: Read>(r: &mut R) -> io::Result<u8> {
52 Ok(read_bytes::<_, 1>(r)?[0])
53}
54
55pub fn read_u16<R: Read>(r: &mut R) -> io::Result<u16> {
57 read_bytes(r).map(u16::from_le_bytes)
58}
59
60pub fn read_u32<R: Read>(r: &mut R) -> io::Result<u32> {
62 read_bytes(r).map(u32::from_le_bytes)
63}
64
65pub fn read_u64<R: Read>(r: &mut R) -> io::Result<u64> {
67 read_bytes(r).map(u64::from_le_bytes)
68}
69
70pub fn read_raw_vec<R: Read, T, F: FnMut(&mut R) -> io::Result<T>>(
72 mut f: F,
73 len: usize,
74 r: &mut R,
75) -> io::Result<Vec<T>> {
76 let mut res = vec![];
77 for _ in 0 .. len {
78 res.push(f(r)?);
79 }
80 Ok(res)
81}
82
83pub fn read_array<R: Read, T: Debug, F: FnMut(&mut R) -> io::Result<T>, const N: usize>(
85 f: F,
86 r: &mut R,
87) -> io::Result<[T; N]> {
88 read_raw_vec(f, N, r).map(|vec| {
89 vec.try_into().expect(
90 "read vector of specific length yet couldn't transform to an array of the same length",
91 )
92 })
93}
94
95pub fn read_vec<R: Read, T, F: FnMut(&mut R) -> io::Result<T>>(
101 f: F,
102 length_bound: Option<usize>,
103 r: &mut R,
104) -> io::Result<Vec<T>> {
105 let declared_length: usize = VarInt::read(r)?;
106 if let Some(length_bound) = length_bound {
107 if declared_length > length_bound {
108 Err(io::Error::other("vector exceeds bound on length"))?;
109 }
110 }
111 read_raw_vec(f, declared_length, r)
112}