twitch_types/
macros.rs

1/// A basic macro 1.0 implementation of [`aliri_braid`](https://crates.io/crates/aliri_braid)
2#[macro_export]
3#[doc(hidden)]
4macro_rules! manual_braid {
5    (
6        $(#[$meta:meta])*
7
8        $vis:vis struct $Owned:ident;
9        $(#[$_unused_meta:meta])*
10        $visref:vis struct $Borrowed:ident;
11
12    ) => {
13        manual_braid! {
14            @common
15
16            $(#[$meta])*
17
18            $vis struct $Owned;
19            $(#[$_unused_meta])*
20            $visref struct $Borrowed;
21        }
22
23        impl ::std::fmt::Debug for $Owned {
24            #[inline]
25            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
26                <$Borrowed as ::std::fmt::Debug>::fmt(::std::ops::Deref::deref(self), f)
27            }
28        }
29
30        impl ::std::fmt::Debug for $Borrowed {
31            #[inline]
32            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
33                <str as ::std::fmt::Debug>::fmt(&self.0, f)
34            }
35        }
36    };
37
38    (
39        redact($redacted_type:literal);
40
41        $(#[$meta:meta])*
42
43        $vis:vis struct $Owned:ident;
44        $(#[$_unused_meta:meta])*
45        $visref:vis struct $Borrowed:ident;
46
47    ) => {
48        manual_braid! {
49            @common
50
51            $(#[$meta])*
52
53            $vis struct $Owned;
54            $(#[$_unused_meta])*
55            $visref struct $Borrowed;
56        }
57
58        impl ::std::fmt::Debug for $Owned {
59            #[inline]
60            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
61                f.write_str(concat!("[redacted ", $redacted_type, "]"))
62            }
63        }
64
65        impl ::std::fmt::Debug for $Borrowed {
66            #[inline]
67            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
68                f.write_str(concat!("[redacted ", $redacted_type, "]"))
69            }
70        }
71    };
72
73    (
74        @common
75        $(#[$meta:meta])*
76
77        $vis:vis struct $Owned:ident;
78        $(#[$_unused_meta:meta])*
79        $visref:vis struct $Borrowed:ident;
80
81    ) => {
82
83        $(#[$meta])*
84        #[derive(Clone, Hash, PartialEq, Eq)]
85        #[repr(transparent)]
86        pub struct $Owned(String);
87
88        impl $Owned {
89            #[doc = concat!("Constructs a new ", stringify!($Owned))]
90            #[inline]
91            pub const fn new(raw: String) -> Self {
92                Self(raw)
93            }
94            #[inline]
95            #[doc = concat!("Constructs a new", stringify!($Owned), "from a static reference")]
96            #[track_caller]
97            pub fn from_static(raw: &'static str) -> Self {
98                ::std::borrow::ToOwned::to_owned($Borrowed::from_static(raw))
99            }
100            #[doc = concat!("Converts this `", stringify!($Owned), "` into a [`Box<", stringify!($Borrowed), ">`]\n\nThis will drop any excess capacity.")]
101            #[allow(unsafe_code)]
102            #[inline]
103            pub fn into_boxed_ref(self) -> ::std::boxed::Box<$Borrowed> {
104                #[doc = concat!("SAFETY: `", stringify!($Borrowed), "` is `#[repr(transparent)]` around a single `str` field, so a `*mut str` can be safely reinterpreted as a `*mut ", stringify!($Borrowed), "`")]
105                fn _ptr_safety_comment() {}
106
107                let box_str = self.0.into_boxed_str();
108                unsafe {
109                    ::std::boxed::Box::from_raw(::std::boxed::Box::into_raw(box_str) as *mut $Borrowed)
110                }
111            }
112            #[doc = "Unwraps the underlying [`String`] value"]
113            #[inline]
114            pub fn take(self) -> String {
115                self.0
116            }
117        }
118
119        impl ::std::convert::From<&'_ $Borrowed> for $Owned {
120            #[inline]
121            fn from(s: &$Borrowed) -> Self {
122                ::std::borrow::ToOwned::to_owned(s)
123            }
124        }
125
126        impl ::std::convert::From<$Owned> for ::std::string::String {
127            #[inline]
128            fn from(s: $Owned) -> Self {
129                s.0
130            }
131        }
132
133        impl ::std::borrow::Borrow<$Borrowed> for $Owned {
134            #[inline]
135            fn borrow(&self) -> &$Borrowed {
136                ::std::ops::Deref::deref(self)
137            }
138        }
139
140        impl ::std::convert::AsRef<$Borrowed> for $Owned {
141            #[inline]
142            fn as_ref(&self) -> &$Borrowed {
143                ::std::ops::Deref::deref(self)
144            }
145        }
146
147        impl ::std::convert::AsRef<str> for $Owned {
148            #[inline]
149            fn as_ref(&self) -> &str {
150                self.as_str()
151            }
152        }
153
154        impl ::std::convert::From<$Owned> for ::std::boxed::Box<$Borrowed> {
155            #[inline]
156            fn from(r: $Owned) -> Self {
157                r.into_boxed_ref()
158            }
159        }
160
161        impl ::std::convert::From<::std::boxed::Box<$Borrowed>> for $Owned {
162            #[inline]
163            fn from(r: ::std::boxed::Box<$Borrowed>) -> Self {
164                r.into_owned()
165            }
166        }
167
168        impl<'a> ::std::convert::From<::std::borrow::Cow<'a, $Borrowed>> for $Owned {
169            #[inline]
170            fn from(r: ::std::borrow::Cow<'a, $Borrowed>) -> Self {
171                match r {
172                    ::std::borrow::Cow::Borrowed(b) => ::std::borrow::ToOwned::to_owned(b),
173                    ::std::borrow::Cow::Owned(o) => o,
174                }
175            }
176        }
177
178        impl<'a> ::std::convert::From<$Owned> for ::std::borrow::Cow<'a, $Borrowed> {
179            #[inline]
180            fn from(owned: $Owned) -> Self {
181                ::std::borrow::Cow::Owned(owned)
182            }
183        }
184
185        impl ::std::convert::From<::std::string::String> for $Owned {
186            #[inline]
187            fn from(s: ::std::string::String) -> Self {
188                Self::new(s)
189            }
190        }
191
192        impl ::std::convert::From<&'_ str> for $Owned {
193            #[inline]
194            fn from(s: &str) -> Self {
195                Self::new(::std::convert::From::from(s))
196            }
197        }
198
199        impl ::std::convert::From<::std::boxed::Box<str>> for $Owned {
200            #[inline]
201            fn from(s: ::std::boxed::Box<str>) -> Self {
202                Self::new(::std::convert::From::from(s))
203            }
204        }
205
206        impl ::std::str::FromStr for $Owned {
207            type Err = ::std::convert::Infallible;
208            #[inline]
209            fn from_str(s: &str) -> ::std::result::Result<Self, Self::Err> {
210                ::std::result::Result::Ok(::std::convert::From::from(s))
211            }
212        }
213
214        impl ::std::borrow::Borrow<str> for $Owned {
215            #[inline]
216            fn borrow(&self) -> &str {
217                self.as_str()
218            }
219        }
220
221        impl ::std::ops::Deref for $Owned {
222            type Target = $Borrowed;
223            #[inline]
224            fn deref(&self) -> &Self::Target {
225                $Borrowed::from_str(::std::convert::AsRef::as_ref(&self.0))
226            }
227        }
228
229        impl ::std::fmt::Display for $Owned {
230            #[inline]
231            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
232                <$Borrowed as ::std::fmt::Display>::fmt(::std::ops::Deref::deref(self), f)
233            }
234        }
235
236        impl ::std::cmp::Ord for $Owned {
237            #[inline]
238            fn cmp(&self, other: &Self) -> ::std::cmp::Ordering {
239                ::std::cmp::Ord::cmp(&self.0, &other.0)
240            }
241        }
242        // TODO(2023-07-31): false-positive, remove when rust-lang/rust-clippy#11188 is on nightly
243        impl ::std::cmp::PartialOrd for $Owned {
244            #[inline]
245            #[allow(unknown_lints)]
246            #[allow(clippy::non_canonical_partial_ord_impl)]
247            fn partial_cmp(&self, other: &Self) -> ::std::option::Option<::std::cmp::Ordering> {
248                ::std::option::Option::Some(::std::cmp::Ord::cmp(self, other))
249            }
250        }
251
252        #[cfg(feature = "serde")]
253        impl ::serde::Serialize for $Owned {
254            fn serialize<S: ::serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
255                <String as ::serde::Serialize>::serialize(&self.0, serializer)
256            }
257        }
258
259        #[cfg(feature = "serde")]
260        impl<'de> ::serde::Deserialize<'de> for $Owned {
261            fn deserialize<D: ::serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
262                let raw = <String as ::serde::Deserialize<'de>>::deserialize(deserializer)?;
263                Ok(Self::new(raw))
264            }
265        }
266
267        $(#[$meta])*
268        #[repr(transparent)]
269        #[derive(Hash, PartialEq, Eq, PartialOrd, Ord)]
270        pub struct $Borrowed(str);
271
272        impl $Borrowed {
273            #[allow(unsafe_code)]
274            #[inline]
275            #[doc = concat!("Transparently reinterprets the string slice as a strongly-typed ", stringify!($Borrowed))]
276            pub const fn from_str(raw: &str) -> &Self {
277                let ptr: *const str = raw;
278                #[doc = concat!("SAFETY: `", stringify!($Borrowed), "` is `#[repr(transparent)]` around a single `str` field, so a `*const str` can be safely reinterpreted as a `*const ", stringify!($Borrowed), "`")]
279                fn _ptr_safety_comment() {}
280
281                unsafe { &*(ptr as *const Self) }
282            }
283            #[inline]
284            #[doc = concat!("Transparently reinterprets the static string slice as a strongly-typed ", stringify!($Borrowed))]
285            #[track_caller]
286            pub const fn from_static(raw: &'static str) -> &'static Self {
287                Self::from_str(raw)
288            }
289            #[allow(unsafe_code)]
290            #[inline]
291            #[doc = concat!("Converts a [`Box<", stringify!($Borrowed), ">`] into a [`", stringify!($Owned), "`] without copying or allocating")]
292            pub fn into_owned(self: ::std::boxed::Box<$Borrowed>) -> $Owned {
293                #[doc = concat!("SAFETY: `", stringify!($Borrowed), "` is `#[repr(transparent)]` around a single `str` field, so a `*mut str` can be safely reinterpreted as a `*mut ", stringify!($Borrowed), "`")]
294                fn _ptr_safety_comment() {}
295
296                let raw = ::std::boxed::Box::into_raw(self);
297                let boxed = unsafe { ::std::boxed::Box::from_raw(raw as *mut str) };
298                $Owned::new(::std::convert::From::from(boxed))
299            }
300            #[doc = r" Provides access to the underlying value as a string slice."]
301            #[inline]
302            pub const fn as_str(&self) -> &str {
303                &self.0
304            }
305        }
306
307        impl ::std::borrow::ToOwned for $Borrowed {
308            type Owned = $Owned;
309            #[inline]
310            fn to_owned(&self) -> Self::Owned {
311                $Owned(self.0.into())
312            }
313        }
314
315        impl ::std::cmp::PartialEq<$Borrowed> for $Owned {
316            #[inline]
317            fn eq(&self, other: &$Borrowed) -> bool {
318                self.as_str() == other.as_str()
319            }
320        }
321
322        impl ::std::cmp::PartialEq<&'_ $Owned> for $Owned {
323            #[inline]
324            fn eq(&self, other: &&$Owned) -> bool {
325                self.as_str() == other.as_str()
326            }
327        }
328
329        impl ::std::cmp::PartialEq<$Owned> for $Borrowed {
330            #[inline]
331            fn eq(&self, other: &$Owned) -> bool {
332                self.as_str() == other.as_str()
333            }
334        }
335
336        impl ::std::cmp::PartialEq<&'_ $Borrowed> for $Owned {
337            #[inline]
338            fn eq(&self, other: &&$Borrowed) -> bool {
339                self.as_str() == other.as_str()
340            }
341        }
342
343        impl ::std::cmp::PartialEq<$Owned> for &'_ $Borrowed {
344            #[inline]
345            fn eq(&self, other: &$Owned) -> bool {
346                self.as_str() == other.as_str()
347            }
348        }
349
350        impl<'a> ::std::convert::From<&'a str> for &'a $Borrowed {
351            #[inline]
352            fn from(s: &'a str) -> &'a $Borrowed {
353                $Borrowed::from_str(s)
354            }
355        }
356
357        impl ::std::borrow::Borrow<str> for $Borrowed {
358            #[inline]
359            fn borrow(&self) -> &str {
360                &self.0
361            }
362        }
363
364        impl ::std::convert::AsRef<str> for $Borrowed {
365            #[inline]
366            fn as_ref(&self) -> &str {
367                &self.0
368            }
369        }
370
371        impl<'a> ::std::convert::From<&'a $Borrowed> for ::std::borrow::Cow<'a, $Borrowed> {
372            #[inline]
373            fn from(r: &'a $Borrowed) -> Self {
374                ::std::borrow::Cow::Borrowed(r)
375            }
376        }
377
378        impl<'a, 'b: 'a> ::std::convert::From<&'a ::std::borrow::Cow<'b, $Borrowed>>
379            for &'a $Borrowed
380        {
381            #[inline]
382            fn from(r: &'a ::std::borrow::Cow<'b, $Borrowed>) -> &'a $Borrowed {
383                ::std::borrow::Borrow::borrow(r)
384            }
385        }
386
387        impl ::std::convert::From<&'_ $Borrowed> for ::std::rc::Rc<$Borrowed> {
388            #[allow(unsafe_code)]
389            #[inline]
390            fn from(r: &'_ $Borrowed) -> Self {
391                #[doc = concat!("SAFETY: `", stringify!($Borrowed), "` is `#[repr(transparent)]` around a single `str` field, so a `*const str` can be safely reinterpreted as a `*const ", stringify!($Borrowed), "`")]
392                fn _ptr_safety_comment() {}
393
394                let rc = ::std::rc::Rc::<str>::from(r.as_str());
395                unsafe { ::std::rc::Rc::from_raw(::std::rc::Rc::into_raw(rc) as *const $Borrowed) }
396            }
397        }
398
399        impl ::std::convert::From<&'_ $Borrowed> for ::std::sync::Arc<$Borrowed> {
400            #[allow(unsafe_code)]
401            #[inline]
402            fn from(r: &'_ $Borrowed) -> Self {
403                #[doc = concat!("SAFETY: `", stringify!($Borrowed), "` is `#[repr(transparent)]` around a single `str` field, so a `*const str` can be safely reinterpreted as a `*const ", stringify!($Borrowed), "`")]
404                fn _ptr_safety_comment() {}
405
406                let arc = ::std::sync::Arc::<str>::from(r.as_str());
407                unsafe {
408                    ::std::sync::Arc::from_raw(::std::sync::Arc::into_raw(arc) as *const $Borrowed)
409                }
410            }
411        }
412
413        impl ::std::fmt::Display for $Borrowed {
414            #[inline]
415            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
416                <str as ::std::fmt::Display>::fmt(&self.0, f)
417            }
418        }
419
420        #[cfg(feature = "serde")]
421        impl ::serde::Serialize for $Borrowed {
422            fn serialize<S: ::serde::Serializer>(
423                &self,
424                serializer: S,
425            ) -> ::std::result::Result<S::Ok, S::Error> {
426                <str as ::serde::Serialize>::serialize(self.as_str(), serializer)
427            }
428        }
429
430        #[cfg(feature = "serde")]
431        impl<'de: 'a, 'a> ::serde::Deserialize<'de> for &'a $Borrowed {
432            fn deserialize<D: ::serde::Deserializer<'de>>(
433                deserializer: D,
434            ) -> ::std::result::Result<Self, D::Error> {
435                let raw = <&str as ::serde::Deserialize<'de>>::deserialize(deserializer)?;
436                ::std::result::Result::Ok($Borrowed::from_str(raw))
437            }
438        }
439
440        #[cfg(feature = "serde")]
441        impl<'de> ::serde::Deserialize<'de> for ::std::boxed::Box<$Borrowed> {
442            fn deserialize<D: ::serde::Deserializer<'de>>(
443                deserializer: D,
444            ) -> ::std::result::Result<Self, D::Error> {
445                let owned = <$Owned as ::serde::Deserialize<'de>>::deserialize(deserializer)?;
446                ::std::result::Result::Ok(owned.into_boxed_ref())
447            }
448        }
449
450        impl<'a> From<&'a Vec<&'a $Owned>>
451            for $crate::collection::Collection<'a, $Owned>
452        {
453            fn from(v: &'a Vec<&'a $Owned>) -> Self { Self::Borrowed(::std::borrow::Cow::from(v)) }
454        }
455
456        impl<'a> From<&'a Vec<&'a str>>
457            for $crate::collection::Collection<'a, $Owned>
458        {
459            fn from(v: &'a Vec<&'a str>) -> Self { Self::RefStr(::std::borrow::Cow::from(v)) }
460        }
461
462        impl<'a> From<&'a Vec<String>>
463            for $crate::collection::Collection<'a, $Owned>
464        {
465            fn from(v: &'a Vec<String>) -> Self { Self::OwnedString(::std::borrow::Cow::from(v)) }
466        }
467
468        impl<'a> From<Vec<&'a $Borrowed>>
469            for $crate::collection::Collection<'a, $Owned>
470        {
471            fn from(v: Vec<&'a $Borrowed>) -> Self { Self::Ref(::std::borrow::Cow::from(v)) }
472        }
473
474        impl<'a> From<&'a [&'a $Borrowed]>
475            for $crate::collection::Collection<'a, $Owned>
476        {
477            fn from(v: &'a [&'a $Borrowed]) -> Self { Self::Ref(::std::borrow::Cow::from(v)) }
478        }
479
480        impl From<Vec<String>>
481            for $crate::collection::Collection<'_, $Owned>
482        {
483            fn from(v: Vec<String>) -> Self { Self::OwnedString(::std::borrow::Cow::from(v)) }
484        }
485
486        impl<'a> From<&'a [String]>
487            for $crate::collection::Collection<'a, $Owned>
488        {
489            fn from(v: &'a [String]) -> Self { Self::OwnedString(::std::borrow::Cow::from(v)) }
490        }
491
492        impl<'a> From<Vec<&'a String>>
493            for $crate::collection::Collection<'a, $Owned>
494        {
495            fn from(v: Vec<&'a String>) -> Self { Self::BorrowedString(::std::borrow::Cow::from(v)) }
496        }
497
498        impl<'a> From<&'a [&'a String]>
499            for $crate::collection::Collection<'a, $Owned>
500        {
501            fn from(v: &'a [&'a String]) -> Self { Self::BorrowedString(::std::borrow::Cow::from(v)) }
502        }
503
504        impl<'a> From<Vec<&'a str>>
505            for $crate::collection::Collection<'a, $Owned>
506        {
507            fn from(v: Vec<&'a str>) -> Self { Self::RefStr(::std::borrow::Cow::from(v)) }
508        }
509
510        impl<'a> From<&'a [&'a str]>
511            for $crate::collection::Collection<'a, $Owned>
512        {
513            fn from(v: &'a [&'a str]) -> Self { Self::RefStr(::std::borrow::Cow::from(v)) }
514        }
515
516        impl<'a, const N: usize> From<&'a [&'a str; N]>
517            for $crate::collection::Collection<'a, $Owned>
518        {
519            fn from(v: &'a [&'a str; N]) -> Self { Self::RefStr(::std::borrow::Cow::from(v.as_slice())) }
520        }
521
522        impl<'a, const N: usize> From<&'a [$Owned; N]>
523            for $crate::collection::Collection<'a, $Owned>
524        {
525            fn from(v: &'a [$Owned; N]) -> Self { Self::Owned(::std::borrow::Cow::from(v.as_slice())) }
526        }
527
528        impl<'a, const N: usize> From<&'a [String; N]>
529            for $crate::collection::Collection<'a, $Owned>
530        {
531            fn from(v: &'a [String; N]) -> Self { Self::OwnedString(::std::borrow::Cow::from(v.as_slice())) }
532        }
533
534        impl<'a, const N: usize> From<&'a [&'a $Owned; N]>
535            for $crate::collection::Collection<'a, $Owned>
536        {
537            fn from(v: &'a [&'a $Owned; N]) -> Self { Self::Borrowed(::std::borrow::Cow::from(v.as_slice())) }
538        }
539
540        impl<'a, const N: usize> From<&'a [&'a $Borrowed; N]>
541            for $crate::collection::Collection<'a, $Owned>
542        {
543            fn from(v: &'a [&'a $Borrowed; N]) -> Self { Self::Ref(::std::borrow::Cow::Borrowed(v.as_slice())) }
544        }
545
546        impl<'a> From<&'a $Owned>
547            for $crate::collection::Collection<'a, $Owned>
548        {
549            fn from(v: &'a $Owned) -> Self { Self::Owned(::std::borrow::Cow::from(std::slice::from_ref(v))) }
550        }
551
552        impl<'a> From<&'a &'a $Borrowed>
553            for $crate::collection::Collection<'a, $Owned>
554        {
555            fn from(v: &'a &'a $Borrowed) -> Self { Self::Ref(::std::borrow::Cow::from(std::slice::from_ref(v))) }
556        }
557
558        impl<'a> From<&'a &'a str>
559            for $crate::collection::Collection<'a, $Owned>
560        {
561            fn from(v: &'a &'a str) -> Self { Self::RefStr(::std::borrow::Cow::from(std::slice::from_ref(v))) }
562        }
563    }
564}
565
566macro_rules! impl_extra {
567    (validated, $owned:path, $ref:path, $error:path) => {
568        impl<'a> TryFrom<&'a String> for &'a $ref {
569            type Error = $error;
570            fn try_from(string: &'a String) -> Result<Self, $error>  {
571                <$ref>::from_str(string.as_str())
572            }
573        }
574
575        impl_extra!(@all, $owned, $ref);
576    };
577    (no_arb, $owned:path, $ref:path) => {
578        impl<'a> From<&'a String> for &'a $ref {
579            fn from(string: &'a String) -> Self {
580                <$ref>::from_str(string.as_str())
581            }
582        }
583
584        impl_extra!(@all, $owned, $ref);
585    };
586
587    (ascii, $owned:path, $ref:path) => {
588        impl<'a> From<&'a String> for &'a $ref {
589            fn from(string: &'a String) -> Self {
590                <$ref>::from_str(string.as_str())
591            }
592        }
593
594        #[cfg(feature = "arbitrary")]
595        impl<'a> arbitrary::Arbitrary<'a> for &'a $ref {
596            fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> Result<Self, arbitrary::Error> {
597                let string: &str = <&str as arbitrary::Arbitrary>::arbitrary(u)?;
598                let string = if let Some(i) = string.find(|b: char| !b.is_ascii_alphanumeric()) {
599                    let valid = &string[0..i];
600                    valid
601                } else {
602                    string
603                };
604                if string.is_empty() {
605                    Err(arbitrary::Error::IncorrectFormat)
606                } else {
607                    Ok(string.into())
608                }
609            }
610
611            fn arbitrary_take_rest(u: arbitrary::Unstructured<'a>) -> Result<Self, arbitrary::Error> {
612                let string: &str = <&str as arbitrary::Arbitrary>::arbitrary_take_rest(u)?;
613                if  string.as_bytes().iter().any(|b| !b.is_ascii_alphanumeric())|| string.is_empty() {
614                    Err(arbitrary::Error::IncorrectFormat)
615                } else {
616                    Ok(string.into())
617                }
618            }
619
620            #[inline]
621            fn size_hint(depth: usize) -> (usize, Option<usize>) {
622                <&str as arbitrary::Arbitrary>::size_hint(depth)
623            }
624        }
625
626        #[cfg(feature = "arbitrary")]
627        impl<'a> arbitrary::Arbitrary<'a> for $owned {
628            fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> Result<Self, arbitrary::Error> {
629                <&$ref as arbitrary::Arbitrary>::arbitrary(u).map(Into::into)
630            }
631
632            fn arbitrary_take_rest(u: arbitrary::Unstructured<'a>) -> Result<Self, arbitrary::Error> {
633                <&$ref as arbitrary::Arbitrary>::arbitrary_take_rest(u).map(Into::into)
634            }
635
636            #[inline]
637            fn size_hint(depth: usize) -> (usize, Option<usize>) {
638                <&$ref as arbitrary::Arbitrary>::size_hint(depth)
639            }
640        }
641
642        impl_extra!(@all, $owned, $ref);
643    };
644
645    (numeric, $owned:path, $ref:path) => {
646        impl<'a> From<&'a String> for &'a $ref {
647            fn from(string: &'a String) -> Self {
648                <$ref>::from_str(string.as_str())
649            }
650        }
651
652        #[cfg(feature = "arbitrary")]
653        impl<'a> arbitrary::Arbitrary<'a> for &'a $ref {
654            fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> Result<Self, arbitrary::Error> {
655                let string: &str = <&str as arbitrary::Arbitrary>::arbitrary(u)?;
656                let string = if let Some(i) = string.find(|b: char| !b.is_ascii_digit()) {
657                    let valid = &string[0..i];
658                    valid
659                } else {
660                    string
661                };
662                if string.is_empty() {
663                    Err(arbitrary::Error::IncorrectFormat)
664                } else {
665                    Ok(string.into())
666                }
667            }
668
669            fn arbitrary_take_rest(u: arbitrary::Unstructured<'a>) -> Result<Self, arbitrary::Error> {
670                let string: &str = <&str as arbitrary::Arbitrary>::arbitrary_take_rest(u)?;
671                if  string.as_bytes().iter().any(|b| !b.is_ascii_digit()) || string.is_empty() {
672                    Err(arbitrary::Error::IncorrectFormat)
673                } else {
674                    Ok(string.into())
675                }
676            }
677
678            #[inline]
679            fn size_hint(depth: usize) -> (usize, Option<usize>) {
680                <&str as arbitrary::Arbitrary>::size_hint(depth)
681            }
682        }
683
684        #[cfg(feature = "arbitrary")]
685        impl<'a> arbitrary::Arbitrary<'a> for $owned {
686            fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> Result<Self, arbitrary::Error> {
687                <u32 as arbitrary::Arbitrary>::arbitrary(u).map(|i| format!("{i}").into())
688            }
689
690            fn arbitrary_take_rest(u: arbitrary::Unstructured<'a>) -> Result<Self, arbitrary::Error> {
691                <u32 as arbitrary::Arbitrary>::arbitrary_take_rest(u).map(|i| format!("{i}").into())
692            }
693
694            #[inline]
695            fn size_hint(depth: usize) -> (usize, Option<usize>) {
696                <&$ref as arbitrary::Arbitrary>::size_hint(depth)
697            }
698        }
699
700        impl_extra!(@all, $owned, $ref);
701    };
702
703    ($owned:path, $ref:path) => {
704        impl<'a> From<&'a String> for &'a $ref {
705            fn from(string: &'a String) -> Self {
706                <$ref>::from_str(string.as_str())
707            }
708        }
709
710        #[cfg(feature = "arbitrary")]
711        impl<'a> arbitrary::Arbitrary<'a> for &'a $ref {
712            fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> Result<Self, arbitrary::Error> {
713                <&str as arbitrary::Arbitrary>::arbitrary(u).map(Into::into)
714            }
715
716            fn arbitrary_take_rest(u: arbitrary::Unstructured<'a>) -> Result<Self, arbitrary::Error> {
717                <&str as arbitrary::Arbitrary>::arbitrary_take_rest(u).map(Into::into)
718            }
719
720            #[inline]
721            fn size_hint(depth: usize) -> (usize, Option<usize>) {
722                <&str as arbitrary::Arbitrary>::size_hint(depth)
723            }
724        }
725
726        #[cfg(feature = "arbitrary")]
727        impl<'a> arbitrary::Arbitrary<'a> for $owned {
728            fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> Result<Self, arbitrary::Error> {
729                <&$ref as arbitrary::Arbitrary>::arbitrary(u).map(Into::into)
730            }
731
732            fn arbitrary_take_rest(u: arbitrary::Unstructured<'a>) -> Result<Self, arbitrary::Error> {
733                <&$ref as arbitrary::Arbitrary>::arbitrary_take_rest(u).map(Into::into)
734            }
735
736            #[inline]
737            fn size_hint(depth: usize) -> (usize, Option<usize>) {
738                <&$ref as arbitrary::Arbitrary>::size_hint(depth)
739            }
740        }
741
742        impl_extra!(@all, $owned, $ref);
743    };
744    (@all, $owned:path, $ref:path) => {
745        impl $ref {
746            /// Get a
747            #[doc = concat!("[`Cow<'_, ", stringify!($ref), ">`](std::borrow::Cow::Borrowed)")]
748            pub fn as_cow(&self) -> ::std::borrow::Cow<'_, $ref> {
749                self.into()
750            }
751        }
752
753        #[cfg(feature = "zerofrom")]
754        impl<'zf> zerofrom::ZeroFrom<'zf, $ref> for &'zf $ref {
755            #[inline]
756            fn zero_from(other: &'zf $ref) -> Self {
757                other
758            }
759        }
760
761        #[cfg(feature = "zerofrom")]
762        impl<'zf> zerofrom::ZeroFrom<'zf, $owned> for &'zf $ref {
763            #[inline]
764            fn zero_from(other: &'zf $owned) -> Self {
765                other
766            }
767        }
768
769        impl<'a> From<&'a $owned> for &'a $ref {
770            fn from(owned: &'a $owned) -> Self {
771                &*owned
772            }
773        }
774
775        impl<'a> From<&'a $owned> for ::std::borrow::Cow<'a, $ref> {
776            fn from(owned: &'a $owned) -> Self {
777                ::std::borrow::Cow::Borrowed(&*owned)
778            }
779        }
780
781        impl<'a> crate::IntoCow<'a, $ref> for &'a $ref {
782            fn into_cow(self) -> ::std::borrow::Cow<'a, $ref> {
783                ::std::borrow::Cow::Borrowed(self)
784            }
785        }
786
787        impl<'a> crate::IntoCow<'a, $ref> for $owned {
788            fn into_cow(self) -> ::std::borrow::Cow<'a, $ref> {
789                ::std::borrow::Cow::Owned(self)
790            }
791        }
792
793        impl<'a> crate::IntoCow<'a, $ref> for &'a $owned {
794            fn into_cow(self) -> ::std::borrow::Cow<'a, $ref> {
795                ::std::borrow::Cow::Borrowed(self.as_ref())
796            }
797        }
798
799        const _: () = {
800            #[cfg(feature = "arbitrary")]
801            fn assert_arbitrary() {
802                fn assert<'a, T: arbitrary::Arbitrary<'a>>() {}
803                // XXX: Not asserting arbitrary is implemented for borrowed, this is because a validated type might need owned data.
804                // assert::<&$ref>();
805                assert::<$owned>();
806            }
807
808            #[cfg(feature = "zerofrom")]
809            fn assert_zerofrom() {
810                fn assert_borrowed<'zf, T: zerofrom::ZeroFrom<'zf, $ref>>() {}
811                fn assert_owned<'zf, T: zerofrom::ZeroFrom<'zf, $owned>>() {}
812                assert_borrowed::<&$ref>();
813                assert_owned::<&$ref>();
814            }
815        };
816    };
817}