epee_encoding/
io.rs

1/// This module contains `Read` and `Write` traits for no-std,
2///
3/// This was taken from std-shims which is licensed under MIT and
4/// Copyright (c) 2023 Luke Parker.
5use alloc::string::String;
6use alloc::vec;
7use alloc::vec::Vec;
8
9use crate::{Error, Result};
10
11pub trait Read {
12    fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
13
14    fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
15        let read = self.read(buf)?;
16        if read != buf.len() {
17            Err(Error::IO("Reader ran out of bytes"))?;
18        }
19        Ok(())
20    }
21}
22
23impl Read for &[u8] {
24    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
25        let mut read = buf.len();
26        if self.len() < buf.len() {
27            read = self.len();
28        }
29        buf[..read].copy_from_slice(&self[..read]);
30        *self = &self[read..];
31        Ok(read)
32    }
33}
34
35pub trait Write {
36    fn write(&mut self, buf: &[u8]) -> Result<usize>;
37    fn write_all(&mut self, buf: &[u8]) -> Result<()> {
38        if self.write(buf)? != buf.len() {
39            Err(Error::IO("Writer ran out of bytes"))?;
40        }
41        Ok(())
42    }
43}
44
45impl Write for Vec<u8> {
46    fn write(&mut self, buf: &[u8]) -> Result<usize> {
47        self.extend(buf);
48        Ok(buf.len())
49    }
50}
51
52pub(crate) fn read_bytes<R: Read, const N: usize>(r: &mut R) -> Result<[u8; N]> {
53    let mut res = [0; N];
54    r.read_exact(&mut res)?;
55    Ok(res)
56}
57
58pub(crate) fn read_var_bytes<R: Read>(r: &mut R, len: usize) -> Result<Vec<u8>> {
59    let mut res = vec![0; len];
60    r.read_exact(&mut res)?;
61    Ok(res)
62}
63
64pub(crate) fn read_byte<R: Read>(r: &mut R) -> Result<u8> {
65    Ok(read_bytes::<_, 1>(r)?[0])
66}
67
68pub(crate) fn read_string<R: Read>(r: &mut R, len: usize) -> Result<String> {
69    String::from_utf8(read_var_bytes(r, len)?).map_err(|_| Error::Format("Invalid string"))
70}