rocket_community/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 /// # extern crate rocket_community as rocket;
38 /// use rocket::form::name::Key;
39 ///
40 /// let key = Key::new("a:b:c");
41 /// assert_eq!(key.as_str(), "a:b:c");
42 /// ```
43 pub fn new<S: AsRef<str> + ?Sized>(string: &S) -> &Key {
44 Key::ref_cast(string.as_ref())
45 }
46
47 /// Returns an iterator over the indices of `self`, including empty indices.
48 ///
49 /// See the [top-level docs](Self) for a description of "indices".
50 ///
51 /// # Example
52 ///
53 /// ```rust
54 /// # extern crate rocket_community as rocket;
55 /// use rocket::form::name::Key;
56 ///
57 /// let key = Key::new("foo:bar::baz:a.b.c");
58 /// let indices: Vec<_> = key.indices().collect();
59 /// assert_eq!(indices, &["foo", "bar", "", "baz", "a.b.c"]);
60 /// ```
61 pub fn indices(&self) -> impl Iterator<Item = &str> {
62 self.split(':')
63 }
64
65 /// Borrows the underlying string.
66 ///
67 /// # Example
68 ///
69 /// ```rust
70 /// # extern crate rocket_community as rocket;
71 /// use rocket::form::name::Key;
72 ///
73 /// let key = Key::new("a:b:c");
74 /// assert_eq!(key.as_str(), "a:b:c");
75 /// ```
76 pub fn as_str(&self) -> &str {
77 self
78 }
79}
80
81impl Deref for Key {
82 type Target = str;
83
84 fn deref(&self) -> &Self::Target {
85 &self.0
86 }
87}
88
89impl serde::Serialize for Key {
90 fn serialize<S>(&self, ser: S) -> Result<S::Ok, S::Error>
91 where
92 S: serde::Serializer,
93 {
94 self.0.serialize(ser)
95 }
96}
97
98impl<'de: 'a, 'a> serde::Deserialize<'de> for &'a Key {
99 fn deserialize<D>(de: D) -> Result<Self, D::Error>
100 where
101 D: serde::Deserializer<'de>,
102 {
103 <&'a str as serde::Deserialize<'de>>::deserialize(de).map(Key::new)
104 }
105}
106
107impl<I: core::slice::SliceIndex<str, Output = str>> core::ops::Index<I> for Key {
108 type Output = Key;
109
110 #[inline]
111 fn index(&self, index: I) -> &Self::Output {
112 self.0[index].into()
113 }
114}
115
116impl PartialEq<str> for Key {
117 fn eq(&self, other: &str) -> bool {
118 self == Key::new(other)
119 }
120}
121
122impl PartialEq<Key> for str {
123 fn eq(&self, other: &Key) -> bool {
124 Key::new(self) == other
125 }
126}
127
128impl<'a, S: AsRef<str> + ?Sized> From<&'a S> for &'a Key {
129 #[inline]
130 fn from(string: &'a S) -> Self {
131 Key::new(string)
132 }
133}
134
135impl AsRef<Key> for str {
136 fn as_ref(&self) -> &Key {
137 Key::new(self)
138 }
139}
140
141impl AsRef<Key> for RawStr {
142 fn as_ref(&self) -> &Key {
143 Key::new(self)
144 }
145}
146
147impl std::fmt::Display for Key {
148 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
149 self.0.fmt(f)
150 }
151}