rocket/form/name/
key.rs

1use std::ops::Deref;
2
3use ref_cast::RefCast;
4
5use crate::http::RawStr;
6
7/// A field name key composed of indices.
8///
9/// A form field name key is composed of _indices_, delimited by `:`. The
10/// graphic below illustrates this composition for a single field in
11/// `$name=$value` format:
12///
13/// ```text
14///       food.bart[bar:foo:baz]=some-value
15/// name  |--------------------|
16/// key   |--| |--| |---------|
17/// index |--| |--| |-| |-| |-|
18/// ```
19///
20/// A `Key` is a wrapper around a given key string with methods to easily access
21/// its indices.
22///
23/// # Serialization
24///
25/// A value of this type is serialized exactly as an `&str` consisting of the
26/// entire key.
27#[repr(transparent)]
28#[derive(RefCast, Debug, PartialEq, Eq, Hash)]
29pub struct Key(str);
30
31impl Key {
32    /// Wraps a string as a `Key`. This is cost-free.
33    ///
34    /// # Example
35    ///
36    /// ```rust
37    /// use rocket::form::name::Key;
38    ///
39    /// let key = Key::new("a:b:c");
40    /// assert_eq!(key.as_str(), "a:b:c");
41    /// ```
42    pub fn new<S: AsRef<str> + ?Sized>(string: &S) -> &Key {
43        Key::ref_cast(string.as_ref())
44    }
45
46    /// Returns an iterator over the indices of `self`, including empty indices.
47    ///
48    /// See the [top-level docs](Self) for a description of "indices".
49    ///
50    /// # Example
51    ///
52    /// ```rust
53    /// use rocket::form::name::Key;
54    ///
55    /// let key = Key::new("foo:bar::baz:a.b.c");
56    /// let indices: Vec<_> = key.indices().collect();
57    /// assert_eq!(indices, &["foo", "bar", "", "baz", "a.b.c"]);
58    /// ```
59    pub fn indices(&self) -> impl Iterator<Item = &str> {
60        self.split(':')
61    }
62
63    /// Borrows the underlying string.
64    ///
65    /// # Example
66    ///
67    /// ```rust
68    /// use rocket::form::name::Key;
69    ///
70    /// let key = Key::new("a:b:c");
71    /// assert_eq!(key.as_str(), "a:b:c");
72    /// ```
73    pub fn as_str(&self) -> &str {
74        self
75    }
76}
77
78impl Deref for Key {
79    type Target = str;
80
81    fn deref(&self) -> &Self::Target {
82        &self.0
83    }
84}
85
86impl serde::Serialize for Key {
87    fn serialize<S>(&self, ser: S) -> Result<S::Ok, S::Error>
88        where S: serde::Serializer
89    {
90        self.0.serialize(ser)
91    }
92}
93
94impl<'de: 'a, 'a> serde::Deserialize<'de> for &'a Key {
95    fn deserialize<D>(de: D) -> Result<Self, D::Error>
96        where D: serde::Deserializer<'de>
97    {
98        <&'a str as serde::Deserialize<'de>>::deserialize(de).map(Key::new)
99    }
100}
101
102impl<I: core::slice::SliceIndex<str, Output=str>> core::ops::Index<I> for Key {
103    type Output = Key;
104
105    #[inline]
106    fn index(&self, index: I) -> &Self::Output {
107        self.0[index].into()
108    }
109}
110
111impl PartialEq<str> for Key {
112    fn eq(&self, other: &str) -> bool {
113        self == Key::new(other)
114    }
115}
116
117impl PartialEq<Key> for str {
118    fn eq(&self, other: &Key) -> bool {
119        Key::new(self) == other
120    }
121}
122
123impl<'a, S: AsRef<str> + ?Sized> From<&'a S> for &'a Key {
124    #[inline]
125    fn from(string: &'a S) -> Self {
126        Key::new(string)
127    }
128}
129
130impl AsRef<Key> for str {
131    fn as_ref(&self) -> &Key {
132        Key::new(self)
133    }
134}
135
136impl AsRef<Key> for RawStr {
137    fn as_ref(&self) -> &Key {
138        Key::new(self)
139    }
140}
141
142impl std::fmt::Display for Key {
143    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
144        self.0.fmt(f)
145    }
146}