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