iri_string/template/string/
owned.rs1use core::fmt;
4
5use alloc::borrow::Cow;
6#[cfg(all(feature = "alloc", not(feature = "std")))]
7use alloc::borrow::ToOwned;
8#[cfg(all(feature = "alloc", not(feature = "std")))]
9use alloc::boxed::Box;
10#[cfg(all(feature = "alloc", not(feature = "std")))]
11use alloc::string::String;
12
13use crate::template::error::{CreationError, Error, ErrorKind};
14use crate::template::parser::validate_template_str;
15use crate::template::string::UriTemplateStr;
16
17#[cfg_attr(feature = "serde", derive(serde::Serialize))]
34#[cfg_attr(feature = "serde", serde(transparent))]
35#[derive(Default, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
36pub struct UriTemplateString {
37 inner: String,
39}
40
41impl UriTemplateString {
42 #[inline]
53 #[must_use]
54 pub unsafe fn new_unchecked(s: alloc::string::String) -> Self {
55 Self { inner: s }
62 }
63
64 #[inline]
66 pub fn shrink_to_fit(&mut self) {
67 self.inner.shrink_to_fit()
68 }
69
70 #[inline]
72 #[must_use]
73 pub fn capacity(&self) -> usize {
74 self.inner.capacity()
75 }
76
77 #[inline]
81 #[must_use]
82 pub fn as_slice(&self) -> &UriTemplateStr {
83 self.as_ref()
84 }
85
86 #[inline]
88 pub fn append(&mut self, other: &UriTemplateStr) {
89 self.inner.push_str(other.as_str());
90 debug_assert!(validate_template_str(self.as_str()).is_ok());
91 }
92}
93
94impl AsRef<str> for UriTemplateString {
95 #[inline]
96 fn as_ref(&self) -> &str {
97 &self.inner
98 }
99}
100
101impl AsRef<UriTemplateStr> for UriTemplateString {
102 #[inline]
103 fn as_ref(&self) -> &UriTemplateStr {
104 unsafe { UriTemplateStr::new_always_unchecked(AsRef::<str>::as_ref(self)) }
107 }
108}
109
110impl core::borrow::Borrow<str> for UriTemplateString {
111 #[inline]
112 fn borrow(&self) -> &str {
113 self.as_ref()
114 }
115}
116
117impl core::borrow::Borrow<UriTemplateStr> for UriTemplateString {
118 #[inline]
119 fn borrow(&self) -> &UriTemplateStr {
120 self.as_ref()
121 }
122}
123
124impl ToOwned for UriTemplateStr {
125 type Owned = UriTemplateString;
126
127 #[inline]
128 fn to_owned(&self) -> Self::Owned {
129 self.into()
130 }
131}
132
133impl From<&'_ UriTemplateStr> for UriTemplateString {
134 #[inline]
135 fn from(s: &UriTemplateStr) -> Self {
136 Self {
138 inner: alloc::string::String::from(s.as_str()),
139 }
140 }
141}
142
143impl From<UriTemplateString> for alloc::string::String {
144 #[inline]
145 fn from(s: UriTemplateString) -> Self {
146 s.inner
147 }
148}
149
150impl<'a> From<UriTemplateString> for Cow<'a, UriTemplateStr> {
151 #[inline]
152 fn from(s: UriTemplateString) -> Cow<'a, UriTemplateStr> {
153 Cow::Owned(s)
154 }
155}
156
157impl From<UriTemplateString> for Box<UriTemplateStr> {
158 #[inline]
159 fn from(s: UriTemplateString) -> Box<UriTemplateStr> {
160 let inner: String = s.into();
161 let buf = Box::<str>::from(inner);
162 unsafe {
167 let raw: *mut str = Box::into_raw(buf);
168 Box::<UriTemplateStr>::from_raw(raw as *mut UriTemplateStr)
169 }
170 }
171}
172
173impl TryFrom<&'_ str> for UriTemplateString {
174 type Error = Error;
175
176 #[inline]
177 fn try_from(s: &str) -> Result<Self, Self::Error> {
178 <&UriTemplateStr>::try_from(s).map(Into::into)
179 }
180}
181
182impl TryFrom<&'_ [u8]> for UriTemplateString {
183 type Error = Error;
184
185 #[inline]
186 fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
187 let s = core::str::from_utf8(bytes)
188 .map_err(|e| Error::new(ErrorKind::InvalidUtf8, e.valid_up_to()))?;
189 <&UriTemplateStr>::try_from(s).map(Into::into)
190 }
191}
192
193impl core::convert::TryFrom<alloc::string::String> for UriTemplateString {
194 type Error = CreationError<String>;
195
196 #[inline]
197 fn try_from(s: alloc::string::String) -> Result<Self, Self::Error> {
198 match <&UriTemplateStr>::try_from(s.as_str()) {
199 Ok(_) => {
200 Ok(Self { inner: s })
203 }
204 Err(e) => Err(CreationError::new(e, s)),
205 }
206 }
207}
208
209impl alloc::str::FromStr for UriTemplateString {
210 type Err = Error;
211
212 #[inline]
213 fn from_str(s: &str) -> Result<Self, Self::Err> {
214 TryFrom::try_from(s)
215 }
216}
217
218impl core::ops::Deref for UriTemplateString {
219 type Target = UriTemplateStr;
220
221 #[inline]
222 fn deref(&self) -> &UriTemplateStr {
223 self.as_ref()
224 }
225}
226
227impl_cmp!(str, UriTemplateStr, Cow<'_, str>);
228impl_cmp!(str, &UriTemplateStr, Cow<'_, str>);
229
230impl_cmp!(str, str, UriTemplateString);
231impl_cmp!(str, &str, UriTemplateString);
232impl_cmp!(str, Cow<'_, str>, UriTemplateString);
233impl_cmp!(str, String, UriTemplateString);
234
235impl fmt::Display for UriTemplateString {
236 #[inline]
237 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
238 f.write_str(self.as_str())
239 }
240}
241
242#[cfg(feature = "serde")]
244mod __serde_owned {
245 use super::UriTemplateString;
246
247 use core::fmt;
248
249 #[cfg(all(feature = "alloc", feature = "serde", not(feature = "std")))]
250 use alloc::string::String;
251
252 use serde::{
253 de::{self, Visitor},
254 Deserialize, Deserializer,
255 };
256
257 #[derive(Debug, Clone, Copy)]
259 struct CustomStringVisitor;
260
261 impl Visitor<'_> for CustomStringVisitor {
262 type Value = UriTemplateString;
263
264 #[inline]
265 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
266 f.write_str("URI template string")
267 }
268
269 #[inline]
270 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
271 where
272 E: de::Error,
273 {
274 <UriTemplateString as TryFrom<&str>>::try_from(v).map_err(E::custom)
275 }
276
277 #[cfg(feature = "serde")]
278 #[inline]
279 fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
280 where
281 E: de::Error,
282 {
283 <UriTemplateString as TryFrom<String>>::try_from(v).map_err(E::custom)
284 }
285 }
286
287 impl<'de> Deserialize<'de> for UriTemplateString {
288 #[inline]
289 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
290 where
291 D: Deserializer<'de>,
292 {
293 deserializer.deserialize_str(CustomStringVisitor)
294 }
295 }
296}