bolero_generator/driver/
bytes.rs

1use super::*;
2
3#[derive(Debug)]
4pub struct Driver<I> {
5    input: I,
6    depth: usize,
7    max_depth: usize,
8    len: usize,
9    cursor: usize,
10}
11
12impl<I> Driver<I>
13where
14    I: AsRef<[u8]>,
15{
16    pub fn new(input: I, options: &Options) -> Self {
17        let max_depth = options.max_depth_or_default();
18        let len = options.max_len_or_default().min(input.as_ref().len());
19
20        Self {
21            input,
22            depth: 0,
23            max_depth,
24            len,
25            cursor: 0,
26        }
27    }
28
29    pub fn reset(&mut self, input: I, options: &Options) -> I {
30        let max_depth = options.max_depth_or_default();
31        let len = options.max_len_or_default().min(input.as_ref().len());
32
33        let prev = core::mem::replace(&mut self.input, input);
34        self.depth = 0;
35        self.max_depth = max_depth;
36        self.cursor = 0;
37        self.len = len;
38
39        prev
40    }
41
42    #[inline]
43    pub fn as_slice(&self) -> &[u8] {
44        &self.input.as_ref()[self.cursor..self.len]
45    }
46
47    #[inline]
48    pub fn into_inner(self) -> I {
49        self.input
50    }
51}
52
53impl<I> FillBytes for Driver<I>
54where
55    I: AsRef<[u8]>,
56{
57    #[inline]
58    fn peek_bytes(&mut self, offset: usize, bytes: &mut [u8]) -> Option<()> {
59        let slice = self.as_slice();
60        match slice.len().checked_sub(offset) {
61            None | Some(0) => {
62                // no bytes left so fill in zeros
63                bytes.fill(0);
64            }
65            Some(remaining_len) if remaining_len >= bytes.len() => {
66                let input = &slice[offset..];
67                let input = &input[..bytes.len()];
68                bytes.copy_from_slice(input);
69            }
70            Some(remaining_len) => {
71                let input = &slice[offset..];
72                // we don't have enough bytes to fill the whole output
73                let (head, tail) = bytes.split_at_mut(remaining_len);
74                head.copy_from_slice(input);
75                tail.fill(0);
76            }
77        }
78
79        Some(())
80    }
81
82    #[inline]
83    fn consume_bytes(&mut self, consumed: usize) {
84        let remaining = self.len - self.cursor;
85        let consumed = consumed.min(remaining);
86        self.cursor += consumed;
87    }
88}
89
90impl<I> super::Driver for Driver<I>
91where
92    I: AsRef<[u8]>,
93{
94    gen_from_bytes!();
95
96    #[inline]
97    fn gen_from_bytes<Hint, Gen, T>(&mut self, _hint: Hint, mut produce: Gen) -> Option<T>
98    where
99        Hint: FnOnce() -> (usize, Option<usize>),
100        Gen: FnMut(&[u8]) -> Option<(usize, T)>,
101    {
102        let slice = self.as_slice();
103        let (len, value) = produce(slice)?;
104        self.consume_bytes(len);
105        Some(value)
106    }
107
108    #[inline]
109    fn depth(&self) -> usize {
110        self.depth
111    }
112
113    #[inline]
114    fn set_depth(&mut self, depth: usize) {
115        self.depth = depth;
116    }
117
118    #[inline]
119    fn max_depth(&self) -> usize {
120        self.max_depth
121    }
122}
123
124#[derive(Debug)]
125pub struct ByteSliceDriver<'a>(Driver<&'a [u8]>);
126
127impl<'a> ByteSliceDriver<'a> {
128    pub fn new(input: &'a [u8], options: &Options) -> Self {
129        Self(Driver::new(input, options))
130    }
131
132    #[inline]
133    pub fn as_slice(&self) -> &[u8] {
134        self.0.as_slice()
135    }
136}
137
138impl FillBytes for ByteSliceDriver<'_> {
139    #[inline]
140    fn peek_bytes(&mut self, offset: usize, bytes: &mut [u8]) -> Option<()> {
141        self.0.peek_bytes(offset, bytes)
142    }
143
144    #[inline]
145    fn consume_bytes(&mut self, consumed: usize) {
146        self.0.consume_bytes(consumed)
147    }
148}
149
150impl super::Driver for ByteSliceDriver<'_> {
151    gen_from_bytes!();
152
153    #[inline]
154    fn gen_from_bytes<Hint, Gen, T>(&mut self, hint: Hint, produce: Gen) -> Option<T>
155    where
156        Hint: FnOnce() -> (usize, Option<usize>),
157        Gen: FnMut(&[u8]) -> Option<(usize, T)>,
158    {
159        self.0.gen_from_bytes(hint, produce)
160    }
161
162    #[inline]
163    fn depth(&self) -> usize {
164        self.0.depth
165    }
166
167    #[inline]
168    fn set_depth(&mut self, depth: usize) {
169        self.0.depth = depth;
170    }
171
172    #[inline]
173    fn max_depth(&self) -> usize {
174        self.0.max_depth
175    }
176}