ct_regex_internal/haystack/ext/
hipstr.rs

1use std::{fmt::{self, Debug}, ops::Range};
2
3use hipstr::{Backend, bytes::HipByt, string::HipStr};
4
5use crate::haystack::{HaystackIter, HaystackSlice, IntoHaystack, get_first_char};
6
7fn get_item<I>((_, item): (usize, I)) -> I { item }
8
9impl<'a, B: Backend> HaystackSlice<'a> for HipStr<'a, B> {
10    type Item = char;
11}
12
13/// A haystack type for matching against the [`char`]s in a [`HipStr<'a, B>`](hipstr::HipStr).
14pub struct HipStrStack<'a, B: Backend> {
15    inner: HipStr<'a, B>,
16    index: usize,
17}
18
19impl<'a, B: Backend> IntoHaystack<'a, HipStrStack<'a, B>> for HipStr<'a, B> {
20    fn into_haystack(self) -> HipStrStack<'a, B> {
21        HipStrStack {
22            inner: self,
23            index: 0,
24        }
25    }
26}
27
28impl<'a, B: Backend> Iterator for HipStrStack<'a, B> {
29    type Item = char;
30
31    fn next(&mut self) -> Option<Self::Item> {
32        let (width, first) = get_first_char(&self.remainder_as_slice());
33        // The width won't exceed the remaining slice, so it can't overflow then length.
34        self.index += width;
35        first
36    }
37}
38
39impl<'a, B: Backend> HaystackIter<'a> for HipStrStack<'a, B> {
40    type Slice = HipStr<'a, B>;
41
42    fn current_item(&self) -> Option<Self::Item> {
43        get_item(get_first_char(&self.remainder_as_slice()))
44    }
45
46    fn current_index(&self) -> usize {
47        self.index
48    }
49
50    fn whole_slice(&self) -> Self::Slice {
51        self.inner.clone()
52    }
53
54    fn remainder_as_slice(&self) -> Self::Slice {
55        self.inner.slice(self.index..)
56    }
57
58    fn slice_with(&self, range: Range<usize>) -> Self::Slice {
59        self.inner.slice(range)
60    }
61
62    fn go_to(&mut self, index: usize) {
63        self.index = index;
64    }
65}
66
67impl<'a, B: Backend> Debug for HipStrStack<'a, B> {
68    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69        f.debug_struct("HipStrStack").field("inner", &self.inner).field("index", &self.index).finish()
70    }
71}
72
73impl<'a, B: Backend> Clone for HipStrStack<'a, B> {
74    fn clone(&self) -> Self {
75        Self { inner: self.inner.clone(), index: self.index.clone() }
76    }
77}
78
79impl<'a, B: Backend> HaystackSlice<'a> for HipByt<'a, B> {
80    type Item = u8;
81}
82
83/// A haystack type for matching against the [`u8`]s in a [`HipByt<'a, B>`](hipstr::HipByt).
84pub struct HipBytStack<'a, B: Backend> {
85    inner: HipByt<'a, B>,
86    index: usize,
87}
88
89impl<'a, B: Backend> IntoHaystack<'a, HipBytStack<'a, B>> for HipByt<'a, B> {
90    fn into_haystack(self) -> HipBytStack<'a, B> {
91        HipBytStack {
92            inner: self,
93            index: 0,
94        }
95    }
96}
97
98impl<'a, B: Backend> Iterator for HipBytStack<'a, B> {
99    type Item = u8;
100
101    fn next(&mut self) -> Option<Self::Item> {
102        let byte = self.inner.get(self.index).copied();
103
104        if byte.is_some() {
105            self.index += 1;
106        }
107
108        byte
109    }
110}
111
112impl<'a, B: Backend> HaystackIter<'a> for HipBytStack<'a, B> {
113    type Slice = HipByt<'a, B>;
114
115    fn current_item(&self) -> Option<Self::Item> {
116        self.inner.get(self.index).copied()
117    }
118
119    fn current_index(&self) -> usize {
120        self.index
121    }
122
123    fn whole_slice(&self) -> Self::Slice {
124        self.inner.clone()
125    }
126
127    fn remainder_as_slice(&self) -> Self::Slice {
128        self.inner.slice(self.index..)
129    }
130
131    fn slice_with(&self, range: Range<usize>) -> Self::Slice {
132        self.inner.slice(range)
133    }
134
135    fn go_to(&mut self, index: usize) {
136        self.index = index;
137    }
138}
139
140impl<'a, B: Backend> Debug for HipBytStack<'a, B> {
141    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
142        f.debug_struct("HipBytStack").field("inner", &self.inner).field("index", &self.index).finish()
143    }
144}
145
146impl<'a, B: Backend> Clone for HipBytStack<'a, B> {
147    fn clone(&self) -> Self {
148        Self { inner: self.inner.clone(), index: self.index.clone() }
149    }
150}