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 unsafe { Self::new_always_unchecked(s) }
58 }
59
60 #[inline]
72 #[must_use]
73 pub(super) unsafe fn new_always_unchecked(s: alloc::string::String) -> Self {
74 Self { inner: s }
81 }
82
83 pub(super) fn validate(s: &str) -> Result<(), Error> {
85 validate_template_str(s)
86 }
87
88 #[inline]
90 pub fn shrink_to_fit(&mut self) {
91 self.inner.shrink_to_fit()
92 }
93
94 #[inline]
96 #[must_use]
97 pub fn capacity(&self) -> usize {
98 self.inner.capacity()
99 }
100
101 #[inline]
105 #[must_use]
106 pub fn as_slice(&self) -> &UriTemplateStr {
107 self.as_ref()
108 }
109
110 #[inline]
112 pub fn append(&mut self, other: &UriTemplateStr) {
113 self.inner.push_str(other.as_str());
114 debug_assert_eq!(Self::validate(self.as_str()), Ok(()));
115 }
116}
117
118impl AsRef<str> for UriTemplateString {
119 #[inline]
120 fn as_ref(&self) -> &str {
121 &self.inner
122 }
123}
124
125impl AsRef<UriTemplateStr> for UriTemplateString {
126 #[inline]
127 fn as_ref(&self) -> &UriTemplateStr {
128 unsafe { UriTemplateStr::new_always_unchecked(AsRef::<str>::as_ref(self)) }
131 }
132}
133
134impl core::borrow::Borrow<str> for UriTemplateString {
135 #[inline]
136 fn borrow(&self) -> &str {
137 self.as_ref()
138 }
139}
140
141impl core::borrow::Borrow<UriTemplateStr> for UriTemplateString {
142 #[inline]
143 fn borrow(&self) -> &UriTemplateStr {
144 self.as_ref()
145 }
146}
147
148impl ToOwned for UriTemplateStr {
149 type Owned = UriTemplateString;
150
151 #[inline]
152 fn to_owned(&self) -> Self::Owned {
153 self.into()
154 }
155}
156
157impl From<&'_ UriTemplateStr> for UriTemplateString {
158 #[inline]
159 fn from(s: &UriTemplateStr) -> Self {
160 Self {
162 inner: alloc::string::String::from(s.as_str()),
163 }
164 }
165}
166
167impl From<UriTemplateString> for alloc::string::String {
168 #[inline]
169 fn from(s: UriTemplateString) -> Self {
170 s.inner
171 }
172}
173
174impl<'a> From<UriTemplateString> for Cow<'a, UriTemplateStr> {
175 #[inline]
176 fn from(s: UriTemplateString) -> Cow<'a, UriTemplateStr> {
177 Cow::Owned(s)
178 }
179}
180
181impl From<UriTemplateString> for Box<UriTemplateStr> {
182 #[inline]
183 fn from(s: UriTemplateString) -> Box<UriTemplateStr> {
184 let inner: String = s.into();
185 let buf = Box::<str>::from(inner);
186 unsafe {
191 let raw: *mut str = Box::into_raw(buf);
192 Box::<UriTemplateStr>::from_raw(raw as *mut UriTemplateStr)
193 }
194 }
195}
196
197impl TryFrom<&'_ str> for UriTemplateString {
198 type Error = Error;
199
200 #[inline]
201 fn try_from(s: &str) -> Result<Self, Self::Error> {
202 <&UriTemplateStr>::try_from(s).map(Into::into)
203 }
204}
205
206impl TryFrom<&'_ [u8]> for UriTemplateString {
207 type Error = Error;
208
209 #[inline]
210 fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
211 let s = core::str::from_utf8(bytes)
212 .map_err(|e| Error::new(ErrorKind::InvalidUtf8, e.valid_up_to()))?;
213 <&UriTemplateStr>::try_from(s).map(Into::into)
214 }
215}
216
217impl core::convert::TryFrom<alloc::string::String> for UriTemplateString {
218 type Error = CreationError<String>;
219
220 #[inline]
221 fn try_from(s: alloc::string::String) -> Result<Self, Self::Error> {
222 match <&UriTemplateStr>::try_from(s.as_str()) {
223 Ok(_) => {
224 Ok(Self { inner: s })
227 }
228 Err(e) => Err(CreationError::new(e, s)),
229 }
230 }
231}
232
233impl alloc::str::FromStr for UriTemplateString {
234 type Err = Error;
235
236 #[inline]
237 fn from_str(s: &str) -> Result<Self, Self::Err> {
238 TryFrom::try_from(s)
239 }
240}
241
242impl core::ops::Deref for UriTemplateString {
243 type Target = UriTemplateStr;
244
245 #[inline]
246 fn deref(&self) -> &UriTemplateStr {
247 self.as_ref()
248 }
249}
250
251impl_cmp!(str, UriTemplateStr, Cow<'_, str>);
252impl_cmp!(str, &UriTemplateStr, Cow<'_, str>);
253
254impl_cmp!(str, str, UriTemplateString);
255impl_cmp!(str, &str, UriTemplateString);
256impl_cmp!(str, Cow<'_, str>, UriTemplateString);
257impl_cmp!(str, String, UriTemplateString);
258
259impl fmt::Display for UriTemplateString {
260 #[inline]
261 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
262 f.write_str(self.as_str())
263 }
264}
265
266#[cfg(feature = "serde")]
268mod __serde_owned {
269 use super::UriTemplateString;
270
271 use core::fmt;
272
273 #[cfg(all(feature = "alloc", feature = "serde", not(feature = "std")))]
274 use alloc::string::String;
275
276 use serde::{
277 de::{self, Visitor},
278 Deserialize, Deserializer,
279 };
280
281 #[derive(Debug, Clone, Copy)]
283 struct CustomStringVisitor;
284
285 impl Visitor<'_> for CustomStringVisitor {
286 type Value = UriTemplateString;
287
288 #[inline]
289 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
290 f.write_str("URI template string")
291 }
292
293 #[inline]
294 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
295 where
296 E: de::Error,
297 {
298 <UriTemplateString as TryFrom<&str>>::try_from(v).map_err(E::custom)
299 }
300
301 #[cfg(feature = "serde")]
302 #[inline]
303 fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
304 where
305 E: de::Error,
306 {
307 <UriTemplateString as TryFrom<String>>::try_from(v).map_err(E::custom)
308 }
309 }
310
311 impl<'de> Deserialize<'de> for UriTemplateString {
312 #[inline]
313 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
314 where
315 D: Deserializer<'de>,
316 {
317 deserializer.deserialize_str(CustomStringVisitor)
318 }
319 }
320}