Skip to main content

ureq_proto/
util.rs

1use std::fmt;
2use std::io::{self, Cursor};
3use std::ops::{Deref, DerefMut};
4
5pub(crate) fn find_crlf(b: &[u8]) -> Option<usize> {
6    let cr = b.iter().position(|c| *c == b'\r')?;
7    let maybe_lf = b.get(cr + 1)?;
8    if *maybe_lf == b'\n' { Some(cr) } else { None }
9}
10
11pub(crate) fn compare_lowercase_ascii(a: &str, lowercased: &str) -> bool {
12    if a.len() != lowercased.len() {
13        return false;
14    }
15
16    for (a, b) in a.chars().zip(lowercased.chars()) {
17        if !a.is_ascii() {
18            return false;
19        }
20        let norm = a.to_ascii_lowercase();
21        if norm != b {
22            return false;
23        }
24    }
25
26    true
27}
28
29pub(crate) struct Writer<'a>(pub Cursor<&'a mut [u8]>);
30
31impl<'a> Writer<'a> {
32    pub(crate) fn new(output: &'a mut [u8]) -> Writer<'a> {
33        Self(Cursor::new(output))
34    }
35
36    pub fn len(&self) -> usize {
37        self.0.position() as usize
38    }
39
40    pub fn available(&self) -> usize {
41        self.0.get_ref().len() - self.len()
42    }
43
44    pub(crate) fn try_write(&mut self, block: impl Fn(&mut Self) -> io::Result<()>) -> bool {
45        let pos = self.0.position();
46        let success = (block)(self).is_ok();
47        if !success {
48            self.0.set_position(pos);
49        }
50        success
51    }
52}
53
54impl<'a> io::Write for Writer<'a> {
55    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
56        self.0.write(buf)
57    }
58
59    fn flush(&mut self) -> io::Result<()> {
60        self.0.flush()
61    }
62}
63
64const CHARS_PER_ROW: usize = 16;
65
66impl<'a> Drop for Writer<'a> {
67    fn drop(&mut self) {
68        let len = self.len();
69        log_data(&self.0.get_ref()[..len]);
70    }
71}
72
73pub(crate) fn log_data(data: &[u8]) {
74    for row in data.chunks(CHARS_PER_ROW) {
75        trace!("{:?}", Row(row))
76    }
77}
78
79struct Row<'a>(&'a [u8]);
80
81impl<'a> fmt::Debug for Row<'a> {
82    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83        for i in 0..CHARS_PER_ROW {
84            if let Some(v) = self.0.get(i) {
85                write!(f, "{}", HEX[*v as usize])?
86            } else {
87                write!(f, "--")?;
88            }
89            if i % 2 == 1 {
90                write!(f, " ")?;
91            }
92        }
93        write!(f, " ")?;
94        for i in 0..CHARS_PER_ROW {
95            if let Some(v) = self.0.get(i) {
96                if v.is_ascii_alphanumeric() || v.is_ascii_punctuation() {
97                    write!(f, "{}", *v as char)?;
98                } else {
99                    write!(f, ".")?;
100                }
101            } else {
102                write!(f, ".")?;
103            }
104        }
105        Ok(())
106    }
107}
108
109const HEX: [&str; 256] = [
110    "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a", "0b", "0c", "0d", "0e", "0f",
111    "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1a", "1b", "1c", "1d", "1e", "1f",
112    "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2a", "2b", "2c", "2d", "2e", "2f",
113    "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3a", "3b", "3c", "3d", "3e", "3f",
114    "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4a", "4b", "4c", "4d", "4e", "4f",
115    "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5a", "5b", "5c", "5d", "5e", "5f",
116    "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6a", "6b", "6c", "6d", "6e", "6f",
117    "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7a", "7b", "7c", "7d", "7e", "7f",
118    "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8a", "8b", "8c", "8d", "8e", "8f",
119    "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9a", "9b", "9c", "9d", "9e", "9f",
120    "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "aa", "ab", "ac", "ad", "ae", "af",
121    "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9", "ba", "bb", "bc", "bd", "be", "bf",
122    "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf",
123    "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "da", "db", "dc", "dd", "de", "df",
124    "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef",
125    "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff",
126];
127
128/// Simple impl of an array behaving like a vec.
129#[derive(Clone)]
130pub struct ArrayVec<T, const N: usize> {
131    len: usize,
132    arr: [T; N],
133}
134
135impl<T: PartialEq, const N: usize> PartialEq for ArrayVec<T, N> {
136    fn eq(&self, other: &Self) -> bool {
137        self[..] == other[..]
138    }
139}
140
141impl<T: Eq, const N: usize> Eq for ArrayVec<T, N> {}
142
143impl<T: Default, const N: usize> Default for ArrayVec<T, N> {
144    fn default() -> Self {
145        Self::from_fn(|_| T::default())
146    }
147}
148
149impl<T, const N: usize> Deref for ArrayVec<T, N> {
150    type Target = [T];
151
152    fn deref(&self) -> &Self::Target {
153        &self.arr[..self.len]
154    }
155}
156
157impl<T, const N: usize> DerefMut for ArrayVec<T, N> {
158    fn deref_mut(&mut self) -> &mut Self::Target {
159        &mut self.arr[..self.len]
160    }
161}
162
163impl<T, const N: usize> ArrayVec<T, N> {
164    /// Construct the array.
165    ///
166    /// The function must produces placeholder elements of the type `T`.
167    pub fn from_fn(cb: impl FnMut(usize) -> T) -> Self {
168        Self {
169            len: 0,
170            arr: std::array::from_fn(cb),
171        }
172    }
173
174    /// Add a value T.
175    ///
176    /// Panics if the array is already full.
177    pub fn push(&mut self, value: T) {
178        self.arr[self.len] = value;
179        self.len += 1;
180    }
181
182    /// Try to add a value T to the end of the array.
183    ///
184    /// Returns an error if the array is already full.
185    pub fn try_push(&mut self, value: T) -> Result<(), CapacityError<T>> {
186        if self.len >= N {
187            return Err(CapacityError { element: value });
188        }
189        self.push(value);
190        Ok(())
191    }
192
193    /// Shorten the vec.
194    ///
195    /// This does not drop the elements that are now unused.
196    pub fn truncate(&mut self, len: usize) {
197        assert!(len <= self.len);
198        self.len = len;
199    }
200}
201
202/// An error returned when capacity of an [`ArrayVec`] is exceeded.
203#[derive(PartialEq, Eq, Clone)]
204pub struct CapacityError<T> {
205    /// The element that triggered this error.
206    element: T,
207}
208
209impl<T> CapacityError<T> {
210    /// Returns the element that triggered this error.
211    pub fn element(self) -> T {
212        self.element
213    }
214}
215
216impl<T> std::error::Error for CapacityError<T> {}
217
218impl<T> fmt::Debug for CapacityError<T> {
219    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
220        f.debug_struct("CapacityError").finish()
221    }
222}
223
224impl<T> fmt::Display for CapacityError<T> {
225    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
226        write!(f, "ArrayVec capacity exceeded")
227    }
228}
229
230impl<T, const N: usize> fmt::Debug for ArrayVec<T, N>
231where
232    T: fmt::Debug,
233{
234    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
235        f.debug_struct("ArrayVec")
236            .field("len", &self.len)
237            .field("arr", &&self.arr[..self.len])
238            .finish()
239    }
240}
241
242impl<'a, T, const N: usize> IntoIterator for &'a ArrayVec<T, N> {
243    type Item = &'a T;
244    type IntoIter = core::slice::Iter<'a, T>;
245
246    fn into_iter(self) -> Self::IntoIter {
247        self[..self.len].iter()
248    }
249}
250
251#[cfg(test)]
252mod tests {
253    use super::{ArrayVec, CapacityError};
254
255    #[test]
256    fn array_vec_equality_uses_active_elements() {
257        let mut a = ArrayVec::<_, 4>::from_fn(|_| 0);
258        let mut b = ArrayVec::<_, 4>::from_fn(|_| 99);
259        assert_eq!(a, b);
260
261        a.push(1);
262        b.push(1);
263        assert_eq!(a, b);
264
265        b.push(2);
266        assert_ne!(a, b);
267        b.truncate(1);
268        assert_eq!(a, b);
269
270        b[0] = 3;
271        assert_ne!(a, b);
272
273        fn assert_eq_trait<T: Eq>() {}
274        assert_eq_trait::<ArrayVec<i32, 4>>();
275    }
276
277    #[test]
278    fn array_vec_partial_eq_supports_non_eq_elements() {
279        let mut a = ArrayVec::<f32, 1>::default();
280        a.push(f32::NAN);
281        assert_ne!(a, a);
282    }
283
284    #[test]
285    fn array_vec_default_supports_non_copy_elements_and_large_capacities() {
286        let mut values = ArrayVec::<String, 64>::default();
287        assert!(values.is_empty());
288        for i in 0..64 {
289            values.push(i.to_string());
290        }
291        assert_eq!(values.len(), 64);
292        assert_eq!(values[63], "63");
293    }
294
295    #[test]
296    fn array_vec_default_supports_zero_capacity() {
297        let values = ArrayVec::<String, 0>::default();
298        assert!(values.is_empty());
299        assert_eq!(values, ArrayVec::from_fn(|_| String::from("unused")));
300    }
301
302    #[test]
303    fn array_vec_try_push_checks_capacity() {
304        let mut values = ArrayVec::<_, 4>::default();
305        for i in 0..4 {
306            values.try_push(i).unwrap();
307        }
308        let err = values.try_push(1337).unwrap_err();
309        assert_eq!(err, CapacityError { element: 1337 });
310    }
311}