sark_http/field/metadata/map/
record.rs1use core::ops;
4
5#[derive(Clone, Copy)]
7pub struct Span<'a> {
8 first: &'a [u8],
9 second: &'a [u8],
10}
11
12impl<'a> Span<'a> {
13 pub const fn new(first: &'a [u8], second: &'a [u8]) -> Self {
14 Self { first, second }
15 }
16
17 pub const fn from_slice(bytes: &'a [u8]) -> Self {
18 Self::new(bytes, &[])
19 }
20
21 pub const fn len(self) -> usize {
22 self.first.len() + self.second.len()
23 }
24
25 pub const fn is_empty(self) -> bool {
26 self.first.is_empty() && self.second.is_empty()
27 }
28
29 pub const fn parts(self) -> (&'a [u8], &'a [u8]) {
30 (self.first, self.second)
31 }
32
33 pub const fn as_slice(&self) -> Option<&'a [u8]> {
34 if self.second.is_empty() {
35 Some(self.first)
36 } else {
37 None
38 }
39 }
40
41 pub fn get(self, index: usize) -> Option<u8> {
42 if index < self.first.len() {
43 self.first.get(index).copied()
44 } else {
45 self.second.get(index - self.first.len()).copied()
46 }
47 }
48
49 pub fn iter(&self) -> impl Iterator<Item = &'a u8> + Clone {
50 self.first.iter().chain(self.second)
51 }
52
53 pub fn slice(self, range: ops::Range<usize>) -> Option<Self> {
54 let split = self.first.len();
55 if range.end <= split {
56 return self.first.get(range).map(Self::from_slice);
57 }
58 if range.start >= split {
59 return self
60 .second
61 .get(range.start - split..range.end - split)
62 .map(Self::from_slice);
63 }
64 Some(Self::new(
65 self.first.get(range.start..)?,
66 self.second.get(..range.end - split)?,
67 ))
68 }
69
70 pub fn is_equal(self, bytes: &[u8]) -> bool {
71 let split = self.first.len();
72 bytes.len() == self.len()
73 && bytes.get(..split) == Some(self.first)
74 && bytes.get(split..) == Some(self.second)
75 }
76
77 pub fn starts_with(self, prefix: &[u8]) -> bool {
78 let (first, second) = prefix.split_at(prefix.len().min(self.first.len()));
79 self.first.starts_with(first) && self.second.starts_with(second)
80 }
81
82 pub fn ends_with(self, suffix: &[u8]) -> bool {
83 let (first, second) = suffix.split_at(suffix.len().saturating_sub(self.second.len()));
84 self.first.ends_with(first) && self.second.ends_with(second)
85 }
86
87 pub fn eq_ascii(self, bytes: &[u8]) -> bool {
88 bytes.len() == self.len()
89 && self
90 .iter()
91 .copied()
92 .zip(bytes.iter().copied())
93 .all(|(left, right)| left.eq_ignore_ascii_case(&right))
94 }
95
96 pub fn extend(self, out: &mut impl Extend<u8>) {
97 out.extend(self.first.iter().copied());
98 out.extend(self.second.iter().copied());
99 }
100}
101
102impl PartialEq for Span<'_> {
103 fn eq(&self, other: &Self) -> bool {
104 self.first
105 .iter()
106 .chain(self.second)
107 .eq(other.first.iter().chain(other.second))
108 }
109}
110
111impl Eq for Span<'_> {}
112
113#[derive(Copy, Clone, Debug, PartialEq, Eq)]
114pub struct Entry<'a> {
115 pub name: &'a [u8],
116 pub value: &'a [u8],
117 pub indexing: crate::field::Indexing,
118}
119
120impl<'a> Entry<'a> {
121 pub const fn new(name: &'a [u8], value: &'a [u8]) -> Self {
122 Self {
123 name,
124 value,
125 indexing: crate::field::Indexing::Allowed,
126 }
127 }
128
129 pub const fn with_index(mut self, indexing: crate::field::Indexing) -> Self {
130 self.indexing = indexing;
131 self
132 }
133}
134
135impl<'field> From<&Entry<'field>> for Entry<'field> {
136 fn from(field: &Entry<'field>) -> Self {
137 *field
138 }
139}
140
141#[derive(Copy, Clone, PartialEq, Eq)]
142pub struct View<'a> {
143 pub name: Span<'a>,
144 pub value: Span<'a>,
145 pub indexing: crate::field::Indexing,
146}
147
148impl<'a> View<'a> {
149 pub const fn new(name: Span<'a>, value: Span<'a>) -> Self {
150 Self {
151 name,
152 value,
153 indexing: crate::field::Indexing::Allowed,
154 }
155 }
156
157 pub const fn with_index(mut self, indexing: crate::field::Indexing) -> Self {
158 self.indexing = indexing;
159 self
160 }
161}
162
163impl<'a> From<Entry<'a>> for View<'a> {
164 fn from(field: Entry<'a>) -> Self {
165 Self::new(Span::from_slice(field.name), Span::from_slice(field.value))
166 .with_index(field.indexing)
167 }
168}
169
170#[doc(hidden)]
171#[derive(Copy, Clone, PartialEq, Eq)]
172pub struct Match<I, N = Option<I>> {
173 pub exact: Option<I>,
174 pub name: N,
175}
176
177impl<I> Match<I> {
178 #[doc(hidden)]
179 pub const fn none() -> Self {
180 Self {
181 exact: None,
182 name: None,
183 }
184 }
185}