1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// SPDX-License-Identifier: AGPL-3.0-or-later
//! This module contains the [Reader] trait which enables zero-copy deserialization over
//! different input types.
use crate::{error::MapError, Error, Result};

use std::{io::Read, ops::DerefMut};

pub trait Reader<'de> {
    /// Reads exactly enough bytes to fill the given buffer or returns an error.
    fn read_exact(&mut self, buf: &mut [u8]) -> Result<()>;
    /// Returns true if the `borrow_bytes` method is supported by this instance.
    fn can_borrow() -> bool;
    /// Borrows the given number of bytes from this [Reader] starting at the current position.
    fn borrow_bytes(&mut self, len: usize) -> Result<&'de [u8]>;
}

impl<'de, R: ?Sized + Reader<'de>, P: DerefMut<Target = R>> Reader<'de> for P {
    fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
        self.deref_mut().read_exact(buf)
    }

    fn can_borrow() -> bool {
        R::can_borrow()
    }

    fn borrow_bytes(&mut self, len: usize) -> Result<&'de [u8]> {
        self.deref_mut().borrow_bytes(len)
    }
}

/// An adapter over an implementation of the standard library [Read] trait.
pub struct ReadAdapter<R>(R);

impl<R> ReadAdapter<R> {
    pub fn new(read: R) -> Self {
        Self(read)
    }
}

impl<'de, R: Read> Reader<'de> for ReadAdapter<R> {
    fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
        self.0.read_exact(buf).map_error()
    }

    fn can_borrow() -> bool {
        false
    }

    fn borrow_bytes(&mut self, _len: usize) -> Result<&'de [u8]> {
        Err(Error::NotSupported("borrowing from a ReadAdapter"))
    }
}

/// An adapter for reading out of a slice of bytes.
pub struct SliceAdapter<'a>(&'a [u8]);

impl<'a> SliceAdapter<'a> {
    pub fn new(slice: &'a [u8]) -> Self {
        Self(slice)
    }

    fn assert_longer_than(&self, buf_len: usize) -> Result<()> {
        if self.0.len() >= buf_len {
            Ok(())
        } else {
            Err(Error::Eof)
        }
    }
}

impl<'de> Reader<'de> for SliceAdapter<'de> {
    fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
        let buf_len = buf.len();
        self.assert_longer_than(buf_len)?;
        buf.copy_from_slice(&self.0[..buf_len]);
        self.0 = &self.0[buf_len..];
        Ok(())
    }

    fn can_borrow() -> bool {
        true
    }

    fn borrow_bytes(&mut self, len: usize) -> Result<&'de [u8]> {
        self.assert_longer_than(len)?;
        let borrow = &self.0[..len];
        self.0 = &self.0[len..];
        Ok(borrow)
    }
}