1use smartcow::SmartCow;
2use std::{
3 borrow::Cow,
4 iter::FromIterator,
5 ops::{Deref, DerefMut},
6};
7
8#[derive(Debug, Default)]
10pub struct Capture<'key, 'value> {
11 key: SmartCow<'key>,
12 value: SmartCow<'value>,
13}
14
15impl<'key, 'value> Capture<'key, 'value> {
16 pub fn new(key: impl Into<Cow<'key, str>>, value: impl Into<Cow<'value, str>>) -> Self {
19 Self {
20 key: key.into().into(),
21 value: value.into().into(),
22 }
23 }
24
25 pub fn name(&self) -> &str {
27 &self.key
28 }
29
30 pub fn value(&self) -> &str {
32 &self.value
33 }
34
35 pub fn into_owned(self) -> Capture<'static, 'static> {
40 Capture {
41 key: self.key.into_owned(),
42 value: self.value.into_owned(),
43 }
44 }
45}
46
47#[derive(Debug, Default)]
49pub struct Captures<'keys, 'values> {
50 pub(crate) params: Vec<Capture<'keys, 'values>>,
51 pub(crate) wildcard: Option<SmartCow<'values>>,
52}
53
54impl<'keys, 'values> Captures<'keys, 'values> {
55 pub fn new() -> Self {
57 Self::default()
58 }
59
60 pub fn into_owned(self) -> Captures<'static, 'static> {
65 Captures {
66 params: self.params.into_iter().map(|c| c.into_owned()).collect(),
67 wildcard: self.wildcard.map(SmartCow::into_owned),
68 }
69 }
70
71 pub fn params(&self) -> &[Capture] {
73 &self.params[..]
74 }
75
76 pub fn set_wildcard(&mut self, wildcard: impl Into<Cow<'values, str>>) {
79 self.wildcard = Some(wildcard.into().into());
80 }
81
82 pub fn wildcard(&self) -> Option<&str> {
84 self.wildcard.as_deref()
85 }
86
87 pub fn get(&self, key: &str) -> Option<&str> {
89 self.params.iter().find_map(|capture| {
90 if capture.key == key {
91 Some(&*capture.value)
92 } else {
93 None
94 }
95 })
96 }
97
98 pub fn push(&mut self, capture: impl Into<Capture<'keys, 'values>>) {
100 self.params.push(capture.into());
101 }
102
103 pub fn append(&mut self, mut captures: Captures<'keys, 'values>) {
105 self.params.append(&mut captures.params);
106 self.wildcard = captures.wildcard;
107 }
108
109 pub fn iter(&self) -> Iter<'_, '_, '_> {
111 self.into()
112 }
113}
114
115impl<'keys, 'values> Deref for Captures<'keys, 'values> {
116 type Target = Vec<Capture<'keys, 'values>>;
117
118 fn deref(&self) -> &Self::Target {
119 &self.params
120 }
121}
122
123impl<'keys, 'values> DerefMut for Captures<'keys, 'values> {
124 fn deref_mut(&mut self) -> &mut Self::Target {
125 &mut self.params
126 }
127}
128
129impl<'key, 'value> From<(&'key str, &'value str)> for Capture<'key, 'value> {
130 fn from(kv: (&'key str, &'value str)) -> Self {
131 Self {
132 key: kv.0.into(),
133 value: kv.1.into(),
134 }
135 }
136}
137
138impl<'pair, 'key: 'pair, 'value: 'pair> From<&'pair (&'key str, &'value str)>
139 for Capture<'key, 'value>
140{
141 fn from(kv: &'pair (&'key str, &'value str)) -> Self {
142 Self {
143 key: kv.0.into(),
144 value: kv.1.into(),
145 }
146 }
147}
148
149impl<'keys, 'values, F> From<F> for Captures<'keys, 'values>
150where
151 F: IntoIterator<Item = (&'keys str, &'values str)>,
152{
153 fn from(f: F) -> Self {
154 f.into_iter().collect()
155 }
156}
157
158impl<'keys, 'values, I: Into<Capture<'keys, 'values>>> FromIterator<I>
159 for Captures<'keys, 'values>
160{
161 fn from_iter<T: IntoIterator<Item = I>>(iter: T) -> Self {
162 Self {
163 params: iter.into_iter().map(Into::into).collect(),
164 wildcard: None,
165 }
166 }
167}
168
169impl<'keys, 'values, I: Into<Capture<'keys, 'values>>> Extend<I> for Captures<'keys, 'values> {
170 fn extend<T: IntoIterator<Item = I>>(&mut self, iter: T) {
171 self.params.extend(iter.into_iter().map(Into::into));
172 }
173}
174
175impl<'keys, 'values> IntoIterator for Captures<'keys, 'values> {
176 type Item = Capture<'keys, 'values>;
177
178 type IntoIter = std::vec::IntoIter<Self::Item>;
179
180 fn into_iter(self) -> Self::IntoIter {
181 self.params.into_iter()
182 }
183}
184
185#[derive(Debug)]
186pub struct Iter<'captures: 'keys + 'values, 'keys, 'values>(
187 std::slice::Iter<'captures, Capture<'keys, 'values>>,
188);
189impl<'captures: 'keys + 'values, 'keys, 'values> Iterator for Iter<'captures, 'keys, 'values> {
190 type Item = (&'keys str, &'values str);
191
192 fn next(&mut self) -> Option<Self::Item> {
193 self.0.next().map(|c| (c.name(), c.value()))
194 }
195}
196
197impl<'captures: 'keys + 'values, 'keys, 'values> From<&'captures Captures<'keys, 'values>>
198 for Iter<'captures, 'keys, 'values>
199{
200 fn from(value: &'captures Captures<'keys, 'values>) -> Self {
201 Iter(value.params.iter())
202 }
203}
204
205impl<'captures: 'keys + 'values, 'keys, 'values> IntoIterator
206 for &'captures Captures<'keys, 'values>
207{
208 type Item = (&'keys str, &'values str);
209
210 type IntoIter = Iter<'captures, 'keys, 'values>;
211
212 fn into_iter(self) -> Self::IntoIter {
213 self.into()
214 }
215}