rocket/form/name/
name.rs

1use std::ops::Deref;
2
3use ref_cast::RefCast;
4
5use crate::http::RawStr;
6use crate::form::name::*;
7
8/// A field name composed of keys.
9///
10/// A form field name is composed of _keys_, delimited by `.` or `[]`. Keys, in
11/// turn, are composed of _indices_, delimited by `:`. The graphic below
12/// illustrates this composition for a single field in `$name=$value` format:
13///
14/// ```text
15///       food.bart[bar:foo].blam[0_0][1000]=some-value
16/// name  |--------------------------------|
17/// key   |--| |--| |-----|  |--| |-|  |--|
18/// index |--| |--| |-| |-|  |--| |-|  |--|
19/// ```
20///
21/// A `Name` is a wrapper around the field name string with methods to easily
22/// access its sub-components.
23///
24/// # Serialization
25///
26/// A value of this type is serialized exactly as an `&str` consisting of the
27/// entire field name.
28#[repr(transparent)]
29#[derive(RefCast)]
30pub struct Name(str);
31
32impl Name {
33    /// Wraps a string as a `Name`. This is cost-free.
34    ///
35    /// # Example
36    ///
37    /// ```rust
38    /// use rocket::form::name::Name;
39    ///
40    /// let name = Name::new("a.b.c");
41    /// assert_eq!(name.as_str(), "a.b.c");
42    /// ```
43    pub fn new<S: AsRef<str> + ?Sized>(string: &S) -> &Name {
44        Name::ref_cast(string.as_ref())
45    }
46
47    /// Returns an iterator over the keys of `self`, including empty keys.
48    ///
49    /// See the [top-level docs](Self) for a description of "keys".
50    ///
51    /// # Example
52    ///
53    /// ```rust
54    /// use rocket::form::name::Name;
55    ///
56    /// let name = Name::new("apple.b[foo:bar]zoo.[barb].bat");
57    /// let keys: Vec<_> = name.keys().map(|k| k.as_str()).collect();
58    /// assert_eq!(keys, &["apple", "b", "foo:bar", "zoo", "", "barb", "bat"]);
59    /// ```
60    pub fn keys(&self) -> impl Iterator<Item = &Key> {
61        struct Keys<'v>(NameView<'v>);
62
63        impl<'v> Iterator for Keys<'v> {
64            type Item = &'v Key;
65
66            fn next(&mut self) -> Option<Self::Item> {
67                if self.0.exhausted() {
68                    return None;
69                }
70
71                let key = self.0.key_lossy();
72                self.0.shift();
73                Some(key)
74            }
75        }
76
77        Keys(NameView::new(self))
78    }
79
80    /// Returns an iterator over overlapping name prefixes of `self`, each
81    /// succeeding prefix containing one more key than the previous.
82    ///
83    /// # Example
84    ///
85    /// ```rust
86    /// use rocket::form::name::Name;
87    ///
88    /// let name = Name::new("apple.b[foo:bar]");
89    /// let prefixes: Vec<_> = name.prefixes().map(|p| p.as_str()).collect();
90    /// assert_eq!(prefixes, &["apple", "apple.b", "apple.b[foo:bar]"]);
91    ///
92    /// let name = Name::new("a.b.[foo]");
93    /// let prefixes: Vec<_> = name.prefixes().map(|p| p.as_str()).collect();
94    /// assert_eq!(prefixes, &["a", "a.b", "a.b.", "a.b.[foo]"]);
95    /// ```
96    pub fn prefixes(&self) -> impl Iterator<Item = &Name> {
97        struct Prefixes<'v>(NameView<'v>);
98
99        impl<'v> Iterator for Prefixes<'v> {
100            type Item = &'v Name;
101
102            fn next(&mut self) -> Option<Self::Item> {
103                if self.0.exhausted() {
104                    return None;
105                }
106
107                let name = self.0.as_name();
108                self.0.shift();
109                Some(name)
110            }
111        }
112
113        Prefixes(NameView::new(self))
114    }
115
116    /// Borrows the underlying string.
117    ///
118    /// # Example
119    ///
120    /// ```rust
121    /// use rocket::form::name::Name;
122    ///
123    /// let name = Name::new("a.b.c");
124    /// assert_eq!(name.as_str(), "a.b.c");
125    /// ```
126    pub fn as_str(&self) -> &str {
127        &self.0
128    }
129}
130
131impl serde::Serialize for Name {
132    fn serialize<S>(&self, ser: S) -> Result<S::Ok, S::Error>
133        where S: serde::Serializer
134    {
135        self.0.serialize(ser)
136    }
137}
138
139impl<'de: 'a, 'a> serde::Deserialize<'de> for &'a Name {
140    fn deserialize<D>(de: D) -> Result<Self, D::Error>
141        where D: serde::Deserializer<'de>
142    {
143        <&'a str as serde::Deserialize<'de>>::deserialize(de).map(Name::new)
144    }
145}
146
147impl<'a, S: AsRef<str> + ?Sized> From<&'a S> for &'a Name {
148    #[inline]
149    fn from(string: &'a S) -> Self {
150        Name::new(string)
151    }
152}
153
154impl Deref for Name {
155    type Target = str;
156
157    fn deref(&self) -> &Self::Target {
158        &self.0
159    }
160}
161
162impl<I: core::slice::SliceIndex<str, Output=str>> core::ops::Index<I> for Name {
163    type Output = Name;
164
165    #[inline]
166    fn index(&self, index: I) -> &Self::Output {
167        self.0[index].into()
168    }
169}
170
171impl PartialEq for Name {
172    fn eq(&self, other: &Self) -> bool {
173        self.keys().eq(other.keys())
174    }
175}
176
177impl PartialEq<str> for Name {
178    fn eq(&self, other: &str) -> bool {
179        self == Name::new(other)
180    }
181}
182
183impl PartialEq<Name> for str {
184    fn eq(&self, other: &Name) -> bool {
185        Name::new(self) == other
186    }
187}
188
189impl PartialEq<&str> for Name {
190    fn eq(&self, other: &&str) -> bool {
191        self == Name::new(other)
192    }
193}
194
195impl PartialEq<Name> for &str {
196    fn eq(&self, other: &Name) -> bool {
197        Name::new(self) == other
198    }
199}
200
201impl AsRef<Name> for str {
202    fn as_ref(&self) -> &Name {
203        Name::new(self)
204    }
205}
206
207impl AsRef<Name> for RawStr {
208    fn as_ref(&self) -> &Name {
209        Name::new(self)
210    }
211}
212
213impl AsRef<Name> for Name {
214    fn as_ref(&self) -> &Name {
215        self
216    }
217}
218
219impl Eq for Name { }
220
221impl std::hash::Hash for Name {
222    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
223        self.keys().for_each(|k| k.hash(state))
224    }
225}
226
227impl std::fmt::Display for Name {
228    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
229        self.0.fmt(f)
230    }
231}
232
233impl std::fmt::Debug for Name {
234    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
235        self.0.fmt(f)
236    }
237}