validated_slice/macros/
owned.rs

1//! Macros for borrowed custom slice types.
2
3/// Implements std traits for the given custom slice type.
4///
5/// To implement `PartialEq` and `PartialOrd`, use [`impl_cmp_for_owned_slice!`] macro.
6///
7/// # Usage
8///
9/// ## Examples
10///
11/// Assume you want to implement `str` and `String` types manually by yourself.
12/// Then you will have the type definitions below:
13///
14/// ```ignore
15/// /// My `str` type.
16/// #[repr(transparent)]
17/// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
18/// pub struct MyStr([u8]);
19///
20/// /// Spec for `MyStr` type.
21/// enum MyStrSpec {}
22///
23/// impl validated_slice::SliceSpec for MyStrSpec {
24///     // My `str` type.
25///     type Custom = MyStr;
26///     // Backend type of `MyStr`.
27///     type Inner = [u8];
28///     // My `std::str::Utf8Error`.
29///     type Error = MyUtf8Error;
30///
31///     /* ... and methods. */
32/// }
33///
34/// /// My `String` type.
35/// #[derive(Default, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
36/// pub struct AsciiString(Vec<u8>);
37///
38/// /// Spec for `MyString` type.
39/// enum MyStringSpec {}
40///
41/// impl validated_slice::OwnedSliceSpec for MyStringSpec {
42///     // My `String` type.
43///     type Custom = MyString;
44///     // Backend type of `MyString`.
45///     type Inner = Vec<u8>;
46///     // My `std::str::Utf8Error`.
47///     type Error = MyFromUtf8Error;
48///     // Spec of custom borrowed slice type, `MyStr` for this example.
49///     type SliceSpec = MyStrSpec;
50///     // Custom borrowed slice type.
51///     // This should be same as `MyStrSpec::Custom`.
52///     type SliceCustom = MyStr;
53///     // Backend type of the custom borrowed slice type.
54///     // This should be same as `MyStrSpec::Inner`.
55///     type SliceInner = [u8];
56///     // My `std::string::FromUtf8Error`.
57///     // This should be same as `MyStrSpec::Error`.
58///     type SliceError = MyFromUtf8Error;
59///
60///     /* ... and methods. */
61/// }
62/// ```
63///
64/// Then you can implement std traits as below:
65///
66/// ```ignore
67/// validated_slice::impl_std_traits_for_owned_slice! {
68///     // `Std` is omissible.
69///     Std {
70///         // Module identifier of `core` crate.
71///         // Default is `std`.
72///         core: core,
73///         // Module identifier of `alloc` crate.
74///         // Default is `std`.
75///         alloc: alloc,
76///     };
77///     Spec {
78///         spec: MyStringSpec,
79///         custom: MyString,
80///         inner: Vec<u8>,
81///         error: MyFromUtf8Error,
82///         slice_custom: MyStr,
83///         slice_inner: [u8],
84///         slice_error: MyUtf8Error,
85///     };
86///     { AsRef<[u8]> };
87///     { AsRef<str> };
88///     { AsRef<{Custom}> };
89///     { ToOwned<Owned = {Custom}> for {SliceCustom} };
90///     { TryFrom<&{SliceInner}> };
91///     { TryFrom<{Inner}> };
92///     /* ... and more traits you want! */
93/// }
94/// ```
95///
96/// ## Core and alloc
97///
98/// For `no_std` use, the macro uses custom `core` and `alloc` crate if given.
99/// You can support both nostd and non-nostd environment as below:
100///
101/// ```ignore
102/// // Use `std` when available.
103/// #[cfg(feature = "std")]
104/// use alloc as std;
105/// // Use external `alloc` crate when nostd.
106/// #[cfg(not(feature = "std"))]
107/// use alloc;
108///
109/// validated_slice::impl_std_traits_for_owned_slice! {
110///     Std {
111///         core: core,
112///         alloc: alloc,
113///     };
114///     Spec { /* ... */ };
115///     /* ... */
116/// }
117/// ```
118///
119/// ## Type names
120///
121/// As type name, you can use `{Custom}` and `{Inner}` instead of a real type name.
122/// They are replaced to the specified custom and inner types.
123///
124/// `Arc<ty>`, `Box<ty>`, `Cow<ty>`, and `Rc<ty>` will be also replaced to `std::sync::Arc<ty>`,
125/// `std::boxed::Box<ty>`, `std::borrow::Cow<'_, ty>`, and `std::rc::Rc<ty>`, respectively.
126/// They are checked symbolically, so they cannot be specified by type aliases, or
127/// path names such as `std::sync::Arc<ty>`.
128///
129/// ## Supported trait impls
130///
131/// **NOTE**: To implemente `PartialEq` and `PartialOrd`, use `impl_cmp_for_owned_slice!` macro.
132///
133/// Each trait impl is specified by `{ TraitName<TyParams> for TyImplTarget };` format.
134/// `<TyParams>` part and `for TyImplTarget` part is optional.
135///
136/// Default impl target is `{Custom}`, and it should NOT be specified explicitly.
137/// Explicit `for {Custom}` is not supported and will cause compile error.
138///
139/// Supported trait impls are:
140///
141/// * `std::borrow`
142///     + `{ Borrow<{SliceCustom}> };`
143///     + `{ Borrow<any_ty> };`
144///     + `{ BorrowMut<{SliceCustom}> };`
145///     + `{ BorrowMut<any_ty> };`
146///     + `{ ToOwned<Owned = {Custom}> for {SliceCustom} };`
147/// * `std::convert`
148///     + `{ AsMut<{SliceCustom}> };`
149///     + `{ AsMut<any_ty> };`
150///     + `{ AsRef<{SliceCustom}> };`
151///     + `{ AsRef<any_ty> };`
152///     + `{ From<&{SliceInner}> };`
153///     + `{ From<&{SliceCustom}> };`
154///     + `{ From<{Inner}> };`
155///     + `{ From<{Custom}> for {Inner} };`
156///     + `{ TryFrom<&{SliceInner}> };`
157///     + `{ TryFrom<{Inner}> };`
158/// * `std::default`
159///     + `{ Default };`
160///         - Note that this redirects to trait impls for `{SliceCustom}`, rather than for `{Inner}`
161///           or `{SliceInner}`.
162/// * `std::fmt`
163///     + `{ Debug };`
164///     + `{ Display };`
165///     + Note that these redirects to trait impls for `{SliceCustom}`, rather than for `{Inner}` or
166///       `{SliceInner}`.
167/// * `std::ops`
168///     + `{ Deref<Target = {SliceCustom}> };`
169///     + `{ DerefMut<Target = {SliceCustom}> };`
170/// * `std::str`
171///     + `{ FromStr };`
172///
173/// [`impl_cmp_for_owned_slice!`]: macro.impl_cmp_for_owned_slice.html
174#[macro_export]
175macro_rules! impl_std_traits_for_owned_slice {
176    (
177        Std {
178            core: $core:ident,
179            alloc: $alloc:ident,
180        };
181        Spec {
182            spec: $spec:ty,
183            custom: $custom:ty,
184            inner: $inner:ty,
185            error: $error:ty,
186            slice_custom: $slice_custom:ty,
187            slice_inner: $slice_inner:ty,
188            slice_error: $slice_error:ty,
189        };
190        $({$($rest:tt)*});* $(;)?
191    ) => {
192        $(
193            $crate::impl_std_traits_for_owned_slice! {
194                @impl; ({$core, $alloc}, $spec, $custom, $inner, $error,
195                    <$spec as $crate::OwnedSliceSpec>::SliceSpec, $slice_custom, $slice_inner,
196                    $slice_error);
197                rest=[$($rest)*];
198            }
199        )*
200    };
201
202    (
203        Spec {
204            spec: $spec:ty,
205            custom: $custom:ty,
206            inner: $inner:ty,
207            error: $error:ty,
208            slice_custom: $slice_custom:ty,
209            slice_inner: $slice_inner:ty,
210            slice_error: $slice_error:ty,
211        };
212        $({$($rest:tt)*});* $(;)?
213    ) => {
214        $(
215            $crate::impl_std_traits_for_owned_slice! {
216                @impl; ({std, std}, $spec, $custom, $inner, $error,
217                    <$spec as $crate::OwnedSliceSpec>::SliceSpec, $slice_custom, $slice_inner,
218                    $slice_error);
219                rest=[$($rest)*];
220            }
221        )*
222    };
223
224    // std::borrow::Borrow
225    (
226        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
227            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
228        rest=[ Borrow<{SliceCustom}> ];
229    ) => {
230        impl $core::borrow::Borrow<$slice_custom> for $custom {
231            #[inline]
232            fn borrow(&self) -> &$slice_custom {
233                unsafe {
234                    // This is safe only when all of the conditions below are met:
235                    //
236                    // * `$spec::validate(s)` returns `Ok(())`.
237                    //     + This is ensured when `self` is constructed.
238                    // * Safety condition for `<$spec as $crate::OwnedSliceSpec>` is satisfied.
239                    $crate::impl_std_traits_for_owned_slice!(@conv:as_slice, $spec, $slice_spec, self)
240                }
241            }
242        }
243    };
244    (
245        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
246            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
247        rest=[ Borrow<$param:ty> ];
248    ) => {
249        impl $core::borrow::Borrow<$param> for $custom
250        where
251            $slice_inner: $core::borrow::Borrow<$param>,
252        {
253            #[inline]
254            fn borrow(&self) -> &$param {
255                <$spec as $crate::OwnedSliceSpec>::as_slice_inner(self).borrow()
256            }
257        }
258    };
259
260    // std::borrow::BorrowMut
261    (
262        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
263            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
264        rest=[ BorrowMut<{SliceCustom}> ];
265    ) => {
266        impl $core::borrow::BorrowMut<$slice_custom> for $custom {
267            #[inline]
268            fn borrow_mut(&mut self) -> &mut $slice_custom {
269                unsafe {
270                    // This is safe only when all of the conditions below are met:
271                    //
272                    // * `$spec::validate(s)` returns `Ok(())`.
273                    //     + This is ensured when `self` is constructed.
274                    // * Safety condition for `<$spec as $crate::OwnedSliceSpec>` is satisfied.
275                    $crate::impl_std_traits_for_owned_slice!(@conv:as_mut_slice, $spec, $slice_spec, self)
276                }
277            }
278        }
279    };
280    (
281        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
282            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
283        rest=[ BorrowMut<$param:ty> ];
284    ) => {
285        impl $core::borrow::BorrowMut<$param> for $custom
286        where
287            $slice_inner: $core::borrow::BorrowMut<$param>,
288        {
289            #[inline]
290            fn borrow_mut(&mut self) -> &mut $param {
291                <$spec as $crate::OwnedSliceSpec>::as_slice_inner_mut(self).borrow_mut()
292            }
293        }
294    };
295
296    // std::borrow::ToOwned
297    (
298        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
299            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
300        rest=[ ToOwned<Owned = {Custom}> for {SliceCustom} ];
301    ) => {
302        impl $alloc::borrow::ToOwned for $slice_custom
303        where
304            for<'a> $inner: From<&'a $slice_inner>,
305        {
306            type Owned = $custom;
307
308            fn to_owned(&self) -> Self::Owned {
309                let inner = <$inner>::from(<$slice_spec as $crate::SliceSpec>::as_inner(self));
310                unsafe {
311                    // This is safe only when all of the conditions below are met:
312                    //
313                    // * `$spec::validate(self)` returns `Ok(())`.
314                    //     + This is ensured when `self` is created.
315                    // * Safety condition for `<$spec as $crate::OwnedSliceSpec>` is satisfied.
316                    <$spec as $crate::OwnedSliceSpec>::from_inner_unchecked(inner)
317                }
318            }
319        }
320    };
321
322    // std::convert::AsMut
323    (
324        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
325            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
326        rest=[ AsMut<{SliceCustom}> ];
327    ) => {
328        impl $core::convert::AsMut<$slice_custom> for $custom {
329            #[inline]
330            fn as_mut(&mut self) -> &mut $slice_custom {
331                unsafe {
332                    // This is safe only when all of the conditions below are met:
333                    //
334                    // * `$spec::validate(s)` returns `Ok(())`.
335                    //     + This is ensured when `self` is constructed.
336                    // * Safety condition for `<$spec as $crate::OwnedSliceSpec>` is satisfied.
337                    $crate::impl_std_traits_for_owned_slice!(@conv:as_mut_slice, $spec, $slice_spec, self)
338                }
339            }
340        }
341    };
342    (
343        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
344            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
345        rest=[ AsMut<$param:ty> ];
346    ) => {
347        impl $core::convert::AsMut<$param> for $custom
348        where
349            $slice_inner: $core::convert::AsMut<$param>,
350        {
351            #[inline]
352            fn as_mut(&self) -> &$param {
353                <$spec as $crate::OwnedSliceSpec>::as_slice_inner_mut(self).as_mut()
354            }
355        }
356    };
357
358    // std::convert::AsRef
359    (
360        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
361            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
362        rest=[ AsRef<{SliceCustom}> ];
363    ) => {
364        impl $core::convert::AsRef<$slice_custom> for $custom {
365            #[inline]
366            fn as_ref(&self) -> &$slice_custom {
367                unsafe {
368                    // This is safe only when all of the conditions below are met:
369                    //
370                    // * `$spec::validate(s)` returns `Ok(())`.
371                    //     + This is ensured when `self` is constructed.
372                    // * Safety condition for `<$spec as $crate::OwnedSliceSpec>` is satisfied.
373                    $crate::impl_std_traits_for_owned_slice!(@conv:as_slice, $spec, $slice_spec, self)
374                }
375            }
376        }
377    };
378    (
379        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
380            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
381        rest=[ AsRef<$param:ty> ];
382    ) => {
383        impl $core::convert::AsRef<$param> for $custom
384        where
385            $slice_inner: $core::convert::AsRef<$param>,
386        {
387            #[inline]
388            fn as_ref(&self) -> &$param {
389                <$spec as $crate::OwnedSliceSpec>::as_slice_inner(self).as_ref()
390            }
391        }
392    };
393
394    // std::convert::From
395    (
396        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
397            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
398        rest=[ From<&{SliceInner}> ];
399    ) => {
400        impl<'a> $core::convert::From<&'a $slice_inner> for $custom
401        where
402            $inner: From<&'a $slice_inner>,
403        {
404            fn from(s: &'a $slice_inner) -> Self {
405                assert!(
406                    <$slice_spec as $crate::SliceSpec>::validate(s).is_ok(),
407                    "Attempt to convert invalid data: `From<&{}> for {}`",
408                    stringify!($slice_inner), stringify!($custom)
409                );
410                let inner = <$inner>::from(s);
411                unsafe {
412                    // This is safe only when all of the conditions below are met:
413                    //
414                    // * `$spec::validate(s)` returns `Ok(())`.
415                    //     + This is ensured by the leading assert.
416                    // * Safety condition for `<$spec as $crate::OwnedSliceSpec>` is satisfied.
417                    <$spec as $crate::OwnedSliceSpec>::from_inner_unchecked(inner)
418                }
419            }
420        }
421    };
422    (
423        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
424            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
425        rest=[ From<&{SliceCustom}> ];
426    ) => {
427        impl<'a> $core::convert::From<&'a $slice_custom> for $custom
428        where
429            $inner: From<&'a $slice_inner>,
430        {
431            fn from(s: &'a $slice_custom) -> Self {
432                let inner = <$inner>::from(<$slice_spec as $crate::SliceSpec>::as_inner(s));
433                unsafe {
434                    // This is safe only when all of the conditions below are met:
435                    //
436                    // * `$spec::validate(s)` returns `Ok(())`.
437                    //     + This is ensured when `s` is created.
438                    // * Safety condition for `<$spec as $crate::OwnedSliceSpec>` is satisfied.
439                    <$spec as $crate::OwnedSliceSpec>::from_inner_unchecked(inner)
440                }
441            }
442        }
443    };
444    (
445        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
446            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
447        rest=[ From<{Inner}> ];
448    ) => {
449        impl $core::convert::From<$inner> for $custom {
450            fn from(inner: $inner) -> Self {
451                assert!(
452                    <$slice_spec as $crate::SliceSpec>::validate(
453                        <$spec as $crate::OwnedSliceSpec>::inner_as_slice_inner(&inner)
454                    ).is_ok(),
455                    "Attempt to convert invalid data: `From<{}> for {}`",
456                    stringify!($inner), stringify!($custom)
457                );
458                unsafe {
459                    // This is safe only when all of the conditions below are met:
460                    //
461                    // * `$spec::validate(s)` returns `Ok(())`.
462                    //     + This is ensured by the leading assert.
463                    // * Safety condition for `<$spec as $crate::OwnedSliceSpec>` is satisfied.
464                    <$spec as $crate::OwnedSliceSpec>::from_inner_unchecked(inner)
465                }
466            }
467        }
468    };
469    (
470        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
471            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
472        rest=[ From<{Custom}> for {Inner} ];
473    ) => {
474        impl $core::convert::From<$custom> for $inner {
475            fn from(custom: $custom) -> Self {
476                <$spec as $crate::OwnedSliceSpec>::into_inner(custom)
477            }
478        }
479    };
480
481    // std::convert::TryFrom
482    (
483        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
484            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
485        rest=[ TryFrom<&{SliceInner}> ];
486    ) => {
487        impl<'a> $core::convert::TryFrom<&'a $slice_inner> for $custom
488        where
489            $inner: From<&'a $slice_inner>,
490        {
491            type Error = $slice_error;
492
493            fn try_from(s: &'a $slice_inner) -> $core::result::Result<Self, Self::Error> {
494                <$slice_spec as $crate::SliceSpec>::validate(s)?;
495                let inner = <$inner>::from(s);
496                Ok(unsafe {
497                    // This is safe only when all of the conditions below are met:
498                    //
499                    // * `$spec::validate(s)` returns `Ok(())`.
500                    //     + This is ensured by the leading `validate()?` call.
501                    // * Safety condition for `<$spec as $crate::OwnedSliceSpec>` is satisfied.
502                    <$spec as $crate::OwnedSliceSpec>::from_inner_unchecked(inner)
503                })
504            }
505        }
506    };
507    (
508        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
509            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
510        rest=[ TryFrom<{Inner}> ];
511    ) => {
512        impl $core::convert::TryFrom<$inner> for $custom {
513            type Error = $error;
514
515            fn try_from(inner: $inner) -> $core::result::Result<Self, Self::Error> {
516                if let Err(e) = <$slice_spec as $crate::SliceSpec>::validate(
517                    <$spec as $crate::OwnedSliceSpec>::inner_as_slice_inner(&inner)
518                ) {
519                    return Err(<$spec as $crate::OwnedSliceSpec>::convert_validation_error(e, inner));
520                }
521                Ok(unsafe {
522                    // This is safe only when all of the conditions below are met:
523                    //
524                    // * `$spec::validate(s)` returns `Ok(())`.
525                    //     + This is ensured by the leading `validate()?` call.
526                    // * Safety condition for `<$spec as $crate::OwnedSliceSpec>` is satisfied.
527                    <$spec as $crate::OwnedSliceSpec>::from_inner_unchecked(inner)
528                })
529            }
530        }
531    };
532
533    // std::default::Default
534    (
535        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
536            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
537        rest=[ Default ];
538    ) => {
539        impl $core::default::Default for $custom
540        where
541            for<'a> &'a $slice_custom: $core::default::Default,
542            $inner: $core::convert::From<$inner>,
543        {
544            fn default() -> Self {
545                let slice = <&$slice_custom>::default();
546                let slice_inner = <$slice_spec as $crate::SliceSpec>::as_inner(slice);
547                let inner = <$inner>::from(slice_inner);
548                unsafe {
549                    // This is safe only when all of the conditions below are met:
550                    //
551                    // * `$spec::validate(s)` returns `Ok(())`.
552                    //     + This is ensured by `<&$slice_custom>::default()`.
553                    // * Safety condition for `<$spec as $crate::OwnedSliceSpec>` is satisfied.
554                    <$spec as $crate::OwnedSliceSpec>::from_inner_unchecked(inner)
555                }
556            }
557        }
558    };
559
560    // std::fmt::Debug
561    (
562        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
563            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
564        rest=[ Debug ];
565    ) => {
566        impl $core::fmt::Debug for $custom
567        where
568            $slice_custom: $core::fmt::Debug,
569        {
570            fn fmt(&self, f: &mut $core::fmt::Formatter<'_>) -> $core::fmt::Result {
571                let slice = unsafe {
572                    // This is safe only when all of the conditions below are met:
573                    //
574                    // * `$spec::validate(s)` returns `Ok(())`.
575                    //     + This is ensured when `self` is created.
576                    // * Safety condition for `<$spec as $crate::OwnedSliceSpec>` is satisfied.
577                    $crate::impl_std_traits_for_owned_slice!(@conv:as_slice, $spec, $slice_spec, self)
578                };
579                <$slice_custom as $core::fmt::Debug>::fmt(slice, f)
580            }
581        }
582    };
583
584    // std::fmt::Display
585    (
586        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
587            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
588        rest=[ Display ];
589    ) => {
590        impl $core::fmt::Display for $custom
591        where
592            $slice_custom: $core::fmt::Display,
593        {
594            fn fmt(&self, f: &mut $core::fmt::Formatter<'_>) -> $core::fmt::Result {
595                let slice = unsafe {
596                    // This is safe only when all of the conditions below are met:
597                    //
598                    // * `$spec::validate(s)` returns `Ok(())`.
599                    //     + This is ensured when `self` is created.
600                    // * Safety condition for `<$spec as $crate::OwnedSliceSpec>` is satisfied.
601                    $crate::impl_std_traits_for_owned_slice!(@conv:as_slice, $spec, $slice_spec, self)
602                };
603                <$slice_custom as $core::fmt::Display>::fmt(slice, f)
604            }
605        }
606    };
607
608    // std::ops::Deref
609    (
610        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
611            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
612        rest=[ Deref<Target = {SliceCustom}> ];
613    ) => {
614        impl $core::ops::Deref for $custom {
615            type Target = $slice_custom;
616
617            #[inline]
618            fn deref(&self) -> &Self::Target {
619                unsafe {
620                    // This is safe only when all of the conditions below are met:
621                    //
622                    // * `$spec::validate(s)` returns `Ok(())`.
623                    //     + This is ensured when `self` is constructed.
624                    // * Safety condition for `<$spec as $crate::OwnedSliceSpec>` is satisfied.
625                    $crate::impl_std_traits_for_owned_slice!(@conv:as_slice, $spec, $slice_spec, self)
626                }
627            }
628        }
629    };
630
631    // std::ops::DerefMut
632    (
633        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
634            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
635        rest=[ DerefMut<Target = {SliceCustom}> ];
636    ) => {
637        impl $core::ops::DerefMut for $custom {
638            #[inline]
639            fn deref_mut(&mut self) -> &mut Self::Target {
640                unsafe {
641                    // This is safe only when all of the conditions below are met:
642                    //
643                    // * `$spec::validate(s)` returns `Ok(())`.
644                    //     + This is ensured when `self` is constructed.
645                    // * Safety condition for `<$spec as $crate::OwnedSliceSpec>` is satisfied.
646                    $crate::impl_std_traits_for_owned_slice!(@conv:as_mut_slice, $spec, $slice_spec, self)
647                }
648            }
649        }
650    };
651
652    // std::str::FromStr
653    (
654        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
655            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
656        rest=[ FromStr ];
657    ) => {
658        impl $core::str::FromStr for $custom {
659            type Err = $slice_error;
660
661            fn from_str(s: &str) -> $core::result::Result<Self, Self::Err> {
662                // Currently, `$slice_inner` should be `str` for simplicity.
663                // This restriction will be loosened in future.
664                struct EnsureTraitBound
665                where
666                    $slice_spec: $crate::SliceSpec<Inner = str>, {}
667
668                <$slice_spec as $crate::SliceSpec>::validate(s)?;
669                let inner = <$inner>::from(s);
670                Ok(unsafe {
671                    // This is safe only when all of the conditions below are met:
672                    //
673                    // * `$spec::validate(s)` returns `Ok(())`.
674                    //     + This is ensured by the leading `validate()?` call.
675                    // * Safety condition for `<$spec as $crate::OwnedSliceSpec>` is satisfied.
676                    <$spec as $crate::OwnedSliceSpec>::from_inner_unchecked(inner)
677                })
678            }
679        }
680        /*
681        impl<'a> $core::convert::TryFrom<&'a $slice_inner> for $custom
682        where
683            $inner: From<&'a $slice_inner>,
684        {
685            type Error = $slice_error;
686
687            fn try_from(s: &'a $slice_inner) -> $core::result::Result<Self, Self::Error> {
688                <$slice_spec as $crate::SliceSpec>::validate(s)?;
689                let inner = <$inner>::from(s);
690                Ok(unsafe {
691                    // This is safe only when all of the conditions below are met:
692                    //
693                    // * `$spec::validate(s)` returns `Ok(())`.
694                    //     + This is ensured by the leading `validate()?` call.
695                    // * Safety condition for `<$spec as $crate::OwnedSliceSpec>` is satisfied.
696                    <$spec as $crate::OwnedSliceSpec>::from_inner_unchecked(inner)
697                })
698            }
699        }
700        */
701    };
702
703    // Helpers.
704
705    // Converts `&$custom` into `&$slice_custom`.
706    (@conv:as_slice, $spec:ty, $slice_spec:ty, $owned_ref:expr) => {
707        <$slice_spec as $crate::SliceSpec>::from_inner_unchecked(
708            <$spec as $crate::OwnedSliceSpec>::as_slice_inner($owned_ref)
709        )
710    };
711    // Converts `&mut $custom` into `&mut $slice_custom`.
712    (@conv:as_mut_slice, $spec:ty, $slice_spec:ty, $owned_ref:expr) => {
713        <$slice_spec as $crate::SliceSpec>::from_inner_unchecked_mut(
714            <$spec as $crate::OwnedSliceSpec>::as_slice_inner_mut($owned_ref)
715        )
716    };
717
718    // Fallback.
719    (
720        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
721            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
722        rest=[ $($rest:tt)* ];
723    ) => {
724        compile_error!(concat!("Unsupported target: ", stringify!($($rest)*)));
725    };
726}
727
728/// Implements `PartialEq` and `PartialOrd` for the given custom owned slice type.
729///
730/// # Usage
731///
732/// ## Examples
733///
734/// ```ignore
735/// validated_slice::impl_cmp_for_owned_slice! {
736///     // `Std` is omissible.
737///     Std {
738///         // Module identifier of `core` crate.
739///         // Default is `std`.
740///         core: core,
741///         // Module identifier of `alloc` crate.
742///         // Default is `std`.
743///         alloc: alloc,
744///     };
745///     Spec {
746///         spec: AsciiStringSpec,
747///         custom: AsciiString,
748///         inner: String,
749///         slice_custom: AsciiStr,
750///         slice_inner: str,
751///         base: Inner,
752///     };
753///     Cmp { PartialEq, PartialOrd };
754///     // This is same as `#[derive(PartialEq, PartialOrd)]`.
755///     { ({Custom}), ({Custom}) };
756///     { ({Custom}), ({SliceCustom}), rev };
757///     { ({Custom}), (&{SliceCustom}), rev };
758///     // NOTE: `std::borrow::Borrow for AsciiString` is required by `Cow`.
759///     { ({Custom}), (Cow<{SliceCustom}>), rev };
760///     /* ... and more pairs! */
761/// }
762/// ```
763///
764/// ## Core and alloc
765///
766/// For `no_std` use, the macro uses custom `core` and `alloc` crate if given.
767/// You can support both nostd and non-nostd environment as below:
768///
769/// ```ignore
770/// // Use `std` when available.
771/// #[cfg(feature = "std")]
772/// use alloc as std;
773/// // Use external `alloc` crate when nostd.
774/// #[cfg(not(feature = "std"))]
775/// use alloc;
776///
777/// validated_slice::impl_cmp_for_owned_slice! {
778///     Std {
779///         core: core,
780///         alloc: alloc,
781///     }
782///     Spec { /* ... */ };
783///     Cmp { /* ... */ };
784///     /* ... */
785/// }
786/// ```
787///
788/// When you don't need `alloc` crate on nostd build, value of `alloc` field is not used.
789/// Simply specify `alloc: alloc,` or something.
790///
791/// ## Comparison base
792///
793/// The syntax of `Spec` part is very similar to [`impl_std_traits_for_owned_slice!`] macro.
794///
795/// As `base` field, specify `Custom` or `Inner` to decide which comparison should be used
796/// internally.
797/// If you don't define custom comparison, use `base: Inner`.
798///
799/// ## Traits to implement
800///
801/// Comparison traits to implement is specified by `Cmp { .. };` format.
802/// Supproted formats are: `Cmp { PartialEq }`, `Cmp { PartialOrd }`, and
803/// `Cmp { PartialEq, PartialOrd };`.
804///
805/// ## Operand type pairs
806///
807/// Comparisons are implemented between two types, so you should provide list of pairs to implement
808/// comparison.
809///
810/// Supported syntaxes are: `{ (lhs_ty), (rhs_ty) };` and `{ (lhs_ty), (rhs_ty), rev };`.
811///
812/// Parentheses around types are not omittable.
813///
814/// With `, rev`, the macro implements not only `PartialXx<rhs_ty> for lhs_ty`, but also
815/// `PartialXx<lhs_ty> for rhs_ty`.
816///
817/// ## Type names
818///
819/// `{Custom}`, `{Inner}`, `{SliceCustom}`, and `{SliceInner}` will be replaced to the custom slice
820/// type, its inner type, custom borrowed slice type, and its inner type.
821///
822/// `&ty` and `Cow<ty>` are also supported.
823///
824/// Note that in case you specify arbitrary types (other than `{Custom}`, `{Inner}`,
825/// `{SliceCustom}`, `{SliceInner}`, and its variations), that type should implement
826/// `AsRef<base_type>`.
827///
828/// ## Supported types
829///
830/// * `{Custom}`
831/// * `&{Custom}`
832/// * `{SliceCustom}`
833/// * `&{SliceCustom}`
834/// * `Cow<{SliceCustom}>`
835/// * `{Inner}`
836/// * `&{Inner}`
837/// * `{SliceInner}`
838/// * `&{SliceInner}`
839/// * `Cow<{SliceInner}>`
840/// * ... and arbitrary types
841///
842/// Note that, with `base: Custom`, `{Inner}`, `{SliceInner}` and its variants are not supported
843/// (because it does not make sense).
844///
845/// [`impl_std_traits_for_owned_slice!`]: macro.impl_std_traits_for_owned_slice.html
846#[macro_export]
847macro_rules! impl_cmp_for_owned_slice {
848    (
849        Spec {
850            spec: $spec:ty,
851            custom: $custom:ty,
852            inner: $inner:ty,
853            slice_custom: $slice_custom:ty,
854            slice_inner: $slice_inner:ty,
855            base: $base:ident,
856        };
857        Cmp { $($cmp_targets:ident),* };
858        $($rest:tt)*
859    ) => {
860        $crate::impl_cmp_for_owned_slice! {
861            @full;
862            Std {
863                core: std,
864                alloc: std,
865            };
866            Spec {
867                spec: $spec,
868                custom: $custom,
869                inner: $inner,
870                slice_custom: $slice_custom,
871                slice_inner: $slice_inner,
872                base: $base,
873            };
874            Cmp { $($cmp_targets),* };
875            $($rest)*
876        }
877    };
878    (
879        Std {
880            core: $core:ident,
881            alloc: $alloc:ident,
882        };
883        Spec {
884            spec: $spec:ty,
885            custom: $custom:ty,
886            inner: $inner:ty,
887            slice_custom: $slice_custom:ty,
888            slice_inner: $slice_inner:ty,
889            base: $base:ident,
890        };
891        Cmp { $($cmp_targets:ident),* };
892        $($rest:tt)*
893    ) => {
894        $crate::impl_cmp_for_owned_slice! {
895            @full;
896            Std {
897                core: $core,
898                alloc: $alloc,
899            };
900            Spec {
901                spec: $spec,
902                custom: $custom,
903                inner: $inner,
904                slice_custom: $slice_custom,
905                slice_inner: $slice_inner,
906                base: $base,
907            };
908            Cmp { $($cmp_targets),* };
909            $($rest)*
910        }
911    };
912
913    (
914        @full;
915        Std {
916            core: $core:ident,
917            alloc: $alloc:ident,
918        };
919        Spec {
920            spec: $spec:ty,
921            custom: $custom:ty,
922            inner: $inner:ty,
923            slice_custom: $slice_custom:ty,
924            slice_inner: $slice_inner:ty,
925            base: $base:ident,
926        };
927        Cmp { PartialEq, PartialOrd };
928        $({ ($($lhs:tt)*), ($($rhs:tt)*) $(, $($opt:ident),*)? });* $(;)?
929    ) => {
930        $(
931            $crate::impl_cmp_for_owned_slice! {
932                @impl[PartialEq]; ({$core, $alloc}, $spec, $custom, $inner, $slice_custom, $slice_inner, $base);
933                { ($($lhs)*), ($($rhs)*) $(, $($opt),*)? };
934            }
935            $crate::impl_cmp_for_owned_slice! {
936                @impl[PartialOrd]; ({$core, $alloc}, $spec, $custom, $inner, $slice_custom, $slice_inner, $base);
937                { ($($lhs)*), ($($rhs)*) $(, $($opt),*)? };
938            }
939        )*
940    };
941    (
942        @full;
943        Std {
944            core: $core:ident,
945            alloc: $alloc:ident,
946        };
947        Spec {
948            spec: $spec:ty,
949            custom: $custom:ty,
950            inner: $inner:ty,
951            slice_custom: $slice_custom:ty,
952            slice_inner: $slice_inner:ty,
953            base: $base:ident,
954        };
955        Cmp { PartialEq };
956        $({ ($($lhs:tt)*), ($($rhs:tt)*) $(, $($opt:ident),*)? });* $(;)?
957    ) => {
958        $(
959            $crate::impl_cmp_for_owned_slice! {
960                @impl[PartialEq]; ({$core, $alloc}, $spec, $custom, $inner, $slice_custom, $slice_inner, $base);
961                { ($($lhs)*), ($($rhs)*) $(, $($opt),*)? };
962            }
963        )*
964    };
965    (
966        @full;
967        Std {
968            core: $core:ident,
969            alloc: $alloc:ident,
970        };
971        Spec {
972            spec: $spec:ty,
973            custom: $custom:ty,
974            inner: $inner:ty,
975            slice_custom: $slice_custom:ty,
976            slice_inner: $slice_inner:ty,
977            base: $base:ident,
978        };
979        Cmp { PartialOrd };
980        $({ ($($lhs:tt)*), ($($rhs:tt)*) $(, $($opt:ident),*)? });* $(;)?
981    ) => {
982        $(
983            $crate::impl_cmp_for_owned_slice! {
984                @impl[PartialOrd]; ({$core, $alloc}, $spec, $custom, $inner, $slice_custom, $slice_inner, $base);
985                { ($($lhs)*), ($($rhs)*) $(, $($opt),*)? };
986            }
987        )*
988    };
989
990    (
991        @impl[PartialEq]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $slice_custom:ty, $slice_inner:ty, $base:ident);
992        { ($($lhs:tt)*), ($($rhs:tt)*) };
993    ) => {
994        impl $core::cmp::PartialEq<
995            $crate::impl_cmp_for_owned_slice!(@type; ({$core, $alloc}, $custom, $inner, $slice_custom, $slice_inner); { $($rhs)* })
996        > for $crate::impl_cmp_for_owned_slice!(@type; ({$core, $alloc}, $custom, $inner, $slice_custom, $slice_inner); { $($lhs)* })
997        {
998            #[inline]
999            fn eq(&self, other: &$crate::impl_cmp_for_owned_slice!(@type; ({$core, $alloc}, $custom, $inner, $slice_custom, $slice_inner); { $($rhs)* }))
1000                -> bool
1001            {
1002                $crate::impl_cmp_for_owned_slice!(@cmp_fn[PartialEq]; ($slice_custom, $slice_inner, $base))(
1003                    $crate::impl_cmp_for_owned_slice!(@expr[$base]; ({$core, $alloc}, $spec, $slice_custom, $slice_inner); { $($lhs)* }; self),
1004                    $crate::impl_cmp_for_owned_slice!(@expr[$base]; ({$core, $alloc}, $spec, $slice_custom, $slice_inner); { $($rhs)* }; other),
1005                )
1006            }
1007        }
1008    };
1009    (
1010        @impl[PartialEq]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $slice_custom:ty, $slice_inner:ty, $base:ident);
1011        { ($($lhs:tt)*), ($($rhs:tt)*), rev };
1012    ) => {
1013        impl $core::cmp::PartialEq<
1014            $crate::impl_cmp_for_owned_slice!(@type; ({$core, $alloc}, $custom, $inner, $slice_custom, $slice_inner); { $($rhs)* })
1015        > for $crate::impl_cmp_for_owned_slice!(@type; ({$core, $alloc}, $custom, $inner, $slice_custom, $slice_inner); { $($lhs)* })
1016        {
1017            #[inline]
1018            fn eq(&self, other: &$crate::impl_cmp_for_owned_slice!(@type; ({$core, $alloc}, $custom, $inner, $slice_custom, $slice_inner); { $($rhs)* }))
1019                -> bool
1020            {
1021                $crate::impl_cmp_for_owned_slice!(@cmp_fn[PartialEq]; ($slice_custom, $slice_inner, $base))(
1022                    $crate::impl_cmp_for_owned_slice!(@expr[$base]; ({$core, $alloc}, $spec, $slice_custom, $slice_inner); { $($lhs)* }; self),
1023                    $crate::impl_cmp_for_owned_slice!(@expr[$base]; ({$core, $alloc}, $spec, $slice_custom, $slice_inner); { $($rhs)* }; other),
1024                )
1025            }
1026        }
1027        impl $core::cmp::PartialEq<
1028            $crate::impl_cmp_for_owned_slice!(@type; ({$core, $alloc}, $custom, $inner, $slice_custom, $slice_inner); { $($lhs)* })
1029        > for $crate::impl_cmp_for_owned_slice!(@type; ({$core, $alloc}, $custom, $inner, $slice_custom, $slice_inner); { $($rhs)* })
1030        {
1031            #[inline]
1032            fn eq(&self, other: &$crate::impl_cmp_for_owned_slice!(@type; ({$core, $alloc}, $custom, $inner, $slice_custom, $slice_inner); { $($lhs)* }))
1033                -> bool
1034            {
1035                $crate::impl_cmp_for_owned_slice!(@cmp_fn[PartialEq]; ($slice_custom, $slice_inner, $base))(
1036                    $crate::impl_cmp_for_owned_slice!(@expr[$base]; ({$core, $alloc}, $spec, $slice_custom, $slice_inner); { $($rhs)* }; self),
1037                    $crate::impl_cmp_for_owned_slice!(@expr[$base]; ({$core, $alloc}, $spec, $slice_custom, $slice_inner); { $($lhs)* }; other),
1038                )
1039            }
1040        }
1041    };
1042    (
1043        @impl[PartialOrd]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $slice_custom:ty, $slice_inner:ty, $base:ident);
1044        { ($($lhs:tt)*), ($($rhs:tt)*) };
1045    ) => {
1046        impl $core::cmp::PartialOrd<
1047            $crate::impl_cmp_for_owned_slice!(@type; ({$core, $alloc}, $custom, $inner, $slice_custom, $slice_inner); { $($rhs)* })
1048        > for $crate::impl_cmp_for_owned_slice!(@type; ({$core, $alloc}, $custom, $inner, $slice_custom, $slice_inner); { $($lhs)* })
1049        {
1050            #[inline]
1051            fn partial_cmp(&self, other: &$crate::impl_cmp_for_owned_slice!(@type; ({$core, $alloc}, $custom, $inner, $slice_custom, $slice_inner); { $($rhs)* }))
1052                -> $core::option::Option<$core::cmp::Ordering>
1053            {
1054                $crate::impl_cmp_for_owned_slice!(@cmp_fn[PartialOrd]; ($slice_custom, $slice_inner, $base))(
1055                    $crate::impl_cmp_for_owned_slice!(@expr[$base]; ({$core, $alloc}, $spec, $slice_custom, $slice_inner); { $($lhs)* }; self),
1056                    $crate::impl_cmp_for_owned_slice!(@expr[$base]; ({$core, $alloc}, $spec, $slice_custom, $slice_inner); { $($rhs)* }; other),
1057                )
1058            }
1059        }
1060    };
1061    (
1062        @impl[PartialOrd]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $slice_custom:ty, $slice_inner:ty, $base:ident);
1063        { ($($lhs:tt)*), ($($rhs:tt)*), rev };
1064    ) => {
1065        impl $core::cmp::PartialOrd<
1066            $crate::impl_cmp_for_owned_slice!(@type; ({$core, $alloc}, $custom, $inner, $slice_custom, $slice_inner); { $($rhs)* })
1067        > for $crate::impl_cmp_for_owned_slice!(@type; ({$core, $alloc}, $custom, $inner, $slice_custom, $slice_inner); { $($lhs)* })
1068        {
1069            #[inline]
1070            fn partial_cmp(&self, other: &$crate::impl_cmp_for_owned_slice!(@type; ({$core, $alloc}, $custom, $inner, $slice_custom, $slice_inner); { $($rhs)* }))
1071                -> $core::option::Option<$core::cmp::Ordering>
1072            {
1073                $crate::impl_cmp_for_owned_slice!(@cmp_fn[PartialOrd]; ($slice_custom, $slice_inner, $base))(
1074                    $crate::impl_cmp_for_owned_slice!(@expr[$base]; ({$core, $alloc}, $spec, $slice_custom, $slice_inner); { $($lhs)* }; self),
1075                    $crate::impl_cmp_for_owned_slice!(@expr[$base]; ({$core, $alloc}, $spec, $slice_custom, $slice_inner); { $($rhs)* }; other),
1076                )
1077            }
1078        }
1079        impl $core::cmp::PartialOrd<
1080            $crate::impl_cmp_for_owned_slice!(@type; ({$core, $alloc}, $custom, $inner, $slice_custom, $slice_inner); { $($lhs)* })
1081        > for $crate::impl_cmp_for_owned_slice!(@type; ({$core, $alloc}, $custom, $inner, $slice_custom, $slice_inner); { $($rhs)* })
1082        {
1083            #[inline]
1084            fn partial_cmp(&self, other: &$crate::impl_cmp_for_owned_slice!(@type; ({$core, $alloc}, $custom, $inner, $slice_custom, $slice_inner); { $($lhs)* }))
1085                -> $core::option::Option<$core::cmp::Ordering>
1086            {
1087                $crate::impl_cmp_for_owned_slice!(@cmp_fn[PartialOrd]; ($slice_custom, $slice_inner, $base))(
1088                    $crate::impl_cmp_for_owned_slice!(@expr[$base]; ({$core, $alloc}, $spec, $slice_custom, $slice_inner); { $($rhs)* }; self),
1089                    $crate::impl_cmp_for_owned_slice!(@expr[$base]; ({$core, $alloc}, $spec, $slice_custom, $slice_inner); { $($lhs)* }; other),
1090                )
1091            }
1092        }
1093    };
1094
1095    (@type; ({$core:ident, $alloc:ident}, $custom:ty, $inner:ty, $slice_custom:ty, $slice_inner:ty); { {Custom} }) => {
1096        $custom
1097    };
1098    (@type; ({$core:ident, $alloc:ident}, $custom:ty, $inner:ty, $slice_custom:ty, $slice_inner:ty); { &{Custom} }) => {
1099        &$custom
1100    };
1101    (@type; ({$core:ident, $alloc:ident}, $custom:ty, $inner:ty, $slice_custom:ty, $slice_inner:ty); { {SliceCustom} }) => {
1102        $slice_custom
1103    };
1104    (@type; ({$core:ident, $alloc:ident}, $custom:ty, $inner:ty, $slice_custom:ty, $slice_inner:ty); { &{SliceCustom} }) => {
1105        &$slice_custom
1106    };
1107    (@type; ({$core:ident, $alloc:ident}, $custom:ty, $inner:ty, $slice_custom:ty, $slice_inner:ty); { Cow<{SliceCustom}> }) => {
1108        $alloc::borrow::Cow<'_, $slice_custom>
1109    };
1110    (@type; ({$core:ident, $alloc:ident}, $custom:ty, $inner:ty, $slice_custom:ty, $slice_inner:ty); { {Inner} }) => {
1111        $inner
1112    };
1113    (@type; ({$core:ident, $alloc:ident}, $custom:ty, $inner:ty, $slice_custom:ty, $slice_inner:ty); { &{Inner} }) => {
1114        &$inner
1115    };
1116    (@type; ({$core:ident, $alloc:ident}, $custom:ty, $inner:ty, $slice_custom:ty, $slice_inner:ty); { {SliceInner} }) => {
1117        $slice_inner
1118    };
1119    (@type; ({$core:ident, $alloc:ident}, $custom:ty, $inner:ty, $slice_custom:ty, $slice_inner:ty); { &{SliceInner} }) => {
1120        &$slice_inner
1121    };
1122    (@type; ({$core:ident, $alloc:ident}, $custom:ty, $inner:ty, $slice_custom:ty, $slice_inner:ty); { Cow<{SliceInner}> }) => {
1123        $alloc::borrow::Cow<'_, $slice_inner>
1124    };
1125    (@type; ({$core:ident, $alloc:ident}, $custom:ty, $inner:ty, $slice_custom:ty, $slice_inner:ty); { Cow<$ty:ty> }) => { &**$ty };
1126    (@type; ({$core:ident, $alloc:ident}, $custom:ty, $inner:ty, $slice_custom:ty, $slice_inner:ty); { $ty:ty }) => { $ty };
1127
1128    (@cmp_fn[PartialEq]; ($slice_custom:ty, $slice_inner:ty, Inner)) => {
1129        <$slice_inner as core::cmp::PartialEq<$slice_inner>>::eq
1130    };
1131    (@cmp_fn[PartialEq]; ($slice_custom:ty, $slice_inner:ty, Custom)) => {
1132        <$slice_custom as core::cmp::PartialEq<$slice_custom>>::eq
1133    };
1134    (@cmp_fn[PartialOrd]; ($slice_custom:ty, $slice_inner:ty, Inner)) => {
1135        <$slice_inner as core::cmp::PartialOrd<$slice_inner>>::partial_cmp
1136    };
1137    (@cmp_fn[PartialOrd]; ($slice_custom:ty, $slice_inner:ty, Custom)) => {
1138        <$slice_custom as core::cmp::PartialOrd<$slice_custom>>::partial_cmp
1139    };
1140
1141    (@expr[Inner]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { {Custom} }; $expr:expr) => {
1142        <$spec as $crate::OwnedSliceSpec>::as_slice_inner($expr)
1143    };
1144    (@expr[Inner]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { &{Custom} }; $expr:expr) => {
1145        <$spec as $crate::OwnedSliceSpec>::as_slice_inner(*$expr)
1146    };
1147    (@expr[Inner]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { Cow<{Custom}> }; $expr:expr) => {
1148        <$spec as $crate::OwnedSliceSpec>::as_slice_inner(&**$expr)
1149    };
1150    (@expr[Inner]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { {SliceCustom} }; $expr:expr) => {
1151        <<$spec as $crate::OwnedSliceSpec>::SliceSpec as $crate::SliceSpec>::as_inner($expr)
1152    };
1153    (@expr[Inner]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { &{SliceCustom} }; $expr:expr) => {
1154        <<$spec as $crate::OwnedSliceSpec>::SliceSpec as $crate::SliceSpec>::as_inner(*$expr)
1155    };
1156    (@expr[Inner]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { Cow<{SliceCustom}> }; $expr:expr) => {
1157        <<$spec as $crate::OwnedSliceSpec>::SliceSpec as $crate::SliceSpec>::as_inner(&**$expr)
1158    };
1159    (@expr[Inner]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { {Inner} }; $expr:expr) => {
1160        <$spec as $crate::OwnedSliceSpec>::inner_as_slice_inner($expr)
1161    };
1162    (@expr[Inner]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { &{Inner} }; $expr:expr) => {
1163        <$spec as $crate::OwnedSliceSpec>::inner_as_slice_inner(*$expr)
1164    };
1165    (@expr[Inner]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { Cow<{Inner}> }; $expr:expr) => {
1166        <$spec as $crate::OwnedSliceSpec>::inner_as_slice_inner(&**$expr)
1167    };
1168    (@expr[Inner]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { {SliceInner} }; $expr:expr) => {
1169        $expr
1170    };
1171    (@expr[Inner]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { &{SliceInner} }; $expr:expr) => {
1172        *$expr
1173    };
1174    (@expr[Inner]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { Cow<{SliceInner}> }; $expr:expr) => {
1175        &**$expr
1176    };
1177    (@expr[Inner]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { $ty:ty }; $expr:expr) => {
1178        $core::convert::AsRef::<$inner>::as_ref($expr)
1179    };
1180
1181    (@expr[Custom]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { {Custom} }; $expr:expr) => {
1182        unsafe {
1183            // This is safe only when all of the conditions below are met:
1184            //
1185            // * `$spec::validate(s)` returns `Ok(())`.
1186            //     + This is ensured when `$expr` is constructed.
1187            // * Safety condition for `<$spec as $crate::OwnedSliceSpec>` is satisfied.
1188            <<$spec as $crate::OwnedSliceSpec>::SliceSpec as $crate::SliceSpec>::from_inner_unchecked(
1189                <$spec as $crate::OwnedSliceSpec>::as_slice_inner($expr)
1190            )
1191        }
1192    };
1193    (@expr[Custom]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { &{Custom} }; $expr:expr) => {
1194        unsafe {
1195            // This is safe only when all of the conditions below are met:
1196            //
1197            // * `$spec::validate(s)` returns `Ok(())`.
1198            //     + This is ensured when `$expr` is constructed.
1199            // * Safety condition for `<$spec as $crate::OwnedSliceSpec>` is satisfied.
1200            <<$spec as $crate::OwnedSliceSpec>::SliceSpec as $crate::SliceSpec>::from_inner_unchecked(
1201                <$spec as $crate::OwnedSliceSpec>::as_slice_inner(*$expr)
1202            )
1203        }
1204    };
1205    (@expr[Custom]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { Cow<{Custom}> }; $expr:expr) => {
1206        unsafe {
1207            // This is safe only when all of the conditions below are met:
1208            //
1209            // * `$spec::validate(s)` returns `Ok(())`.
1210            //     + This is ensured when `$expr` is constructed.
1211            // * Safety condition for `<$spec as $crate::OwnedSliceSpec>` is satisfied.
1212            <<$spec as $crate::OwnedSliceSpec>::SliceSpec as $crate::SliceSpec>::from_inner_unchecked(
1213                <$spec as $crate::OwnedSliceSpec>::as_slice_inner(&**$expr)
1214            )
1215        }
1216    };
1217    (@expr[Custom]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { {SliceCustom} }; $expr:expr) => {
1218        $expr
1219    };
1220    (@expr[Custom]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { &{SliceCustom} }; $expr:expr) => {
1221        *$expr
1222    };
1223    (@expr[Custom]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { Cow<{SliceCustom}> }; $expr:expr) => {
1224        &**$expr
1225    };
1226    (@expr[Custom]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { $ty:ty }; $expr:expr) => {
1227        $core::convert::AsRef::<$custom>::as_ref($expr)
1228    };
1229
1230    ($($rest:tt)*) => {
1231        compile_error!(stringify!($($rest)*));
1232    };
1233}