barse/reader/
endian_byte_reader.rs

1use std::ops::{Deref, DerefMut};
2
3use crate::{ByteRead, Endian, Result};
4
5use super::DynamicByteReader;
6
7/// [`ByteRead`] wrapper using given endian.
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9pub struct EndianByteReader<R>(R, Endian);
10
11impl<R> EndianByteReader<R> {
12    /// Construct a new [`EndianByteReader`] wrapping given reader and using passed endian.
13    pub fn new<'input>(reader: R, endian: Endian) -> Self
14    where
15        R: ByteRead<'input>,
16    {
17        Self(reader, endian)
18    }
19
20    /// Set the endian in use by this reader.
21    pub fn set_endian(&mut self, endian: Endian) {
22        self.1 = endian;
23    }
24
25    /// Consume self returning the wrapped value.
26    pub fn into_inner(self) -> R {
27        self.0
28    }
29}
30
31impl<R> Deref for EndianByteReader<R> {
32    type Target = R;
33    fn deref(&self) -> &Self::Target {
34        &self.0
35    }
36}
37
38impl<R> DerefMut for EndianByteReader<R> {
39    fn deref_mut(&mut self) -> &mut Self::Target {
40        &mut self.0
41    }
42}
43
44impl<R> AsRef<R> for EndianByteReader<R> {
45    fn as_ref(&self) -> &R {
46        &self.0
47    }
48}
49
50#[deny(clippy::missing_trait_methods)]
51impl<'input, R> ByteRead<'input> for EndianByteReader<R>
52where
53    R: ByteRead<'input>,
54{
55    type AtByteRead = EndianByteReader<R::AtByteRead>;
56
57    fn read_ref(&mut self, count: usize) -> Result<&'input [u8]> {
58        self.0.read_ref(count)
59    }
60
61    fn remaining(&mut self) -> Result<&'input [u8]> {
62        self.0.remaining()
63    }
64
65    fn read<const COUNT: usize>(&mut self) -> Result<[u8; COUNT]> {
66        self.0.read::<COUNT>()
67    }
68
69    fn endian(&self) -> Endian {
70        self.1
71    }
72
73    fn flag<T>(&self) -> Result<&T>
74    where
75        T: std::any::Any,
76    {
77        self.0.flag()
78    }
79
80    fn all(&self) -> Result<&'input [u8]> {
81        self.0.all()
82    }
83
84    fn at(&self, location: usize) -> Result<Self::AtByteRead> {
85        Ok(EndianByteReader(self.0.at(location)?, self.1))
86    }
87
88    fn get_flag(&self, id: std::any::TypeId) -> Option<&dyn std::any::Any> {
89        self.0.get_flag(id)
90    }
91
92    fn into_dynamic(self) -> DynamicByteReader<'input>
93    where
94        Self: Sized + 'input,
95    {
96        DynamicByteReader::from_reader(self)
97    }
98}