dyn_slice/
standard.rs

1use core::{
2    any::Any,
3    borrow::{Borrow, BorrowMut},
4    cmp::{Ordering, PartialEq, PartialOrd},
5    convert::{AsMut, AsRef},
6    fmt::{
7        self, Binary, Debug, Display, LowerExp, LowerHex, Octal, Pointer, UpperExp, UpperHex, Write,
8    },
9    future::Future,
10    hash::{self, BuildHasher, Hasher},
11    iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator},
12    marker::{Send, Sized, Sync},
13    ops::{
14        AddAssign, BitAndAssign, BitOrAssign, BitXorAssign, Deref, DerefMut, DivAssign, Index,
15        IndexMut, MulAssign, RemAssign, ShlAssign, ShrAssign, SubAssign,
16    },
17    ptr::{DynMetadata, Pointee},
18};
19
20use crate::DynSliceMut;
21
22use super::{declare_new_fns, DynSlice};
23
24#[allow(unused)]
25macro_rules! feature_availability {
26    ( $feature:literal ) => {
27        concat!(
28            "(only available with the [`",
29            $feature,
30            "` feature](https://docs.rs/crate/dyn-slice/",
31            env!("CARGO_PKG_VERSION"),
32            "/features))"
33        )
34    };
35}
36
37declare_new_fns!(
38    #[crate = crate]
39    ///
40    /// `DynSlice(Mut)<dyn Any>`, `DynSlice(Mut)<dyn Any + Send>` and `DynSlice(Mut)<dyn Any + Send + Sync>` have a few extra methods:
41    /// - [`DynSlice::is`]
42    /// - [`DynSlice::downcast`]
43    /// - [`DynSliceMut::downcast_mut`]
44    ///
45    /// # Examples
46    ///
47    /// ```
48    /// # use dyn_slice::standard::any;
49    /// let array: [u8; 4] = [1, 2, 4, 8];
50    /// let slice = any::new(&array);
51    ///
52    /// // Assert that the dyn-slice is a slice of `u8`s
53    /// assert!(slice.is::<u8>());
54    /// // Downcast the dyn-slice to a slice of `u8`s
55    /// assert_eq!(slice.downcast::<u8>(), Some(array.as_slice()));
56    /// ```
57    ///
58    /// ```
59    /// # use dyn_slice::standard::any;
60    /// let mut array: [u8; 4] = [1, 2, 4, 8];
61    /// let mut slice = any::new_mut(&mut array);
62    ///
63    /// // Downcast the mutable dyn-slice to a mutable slice of `u8`s
64    /// slice.downcast_mut::<u8>().unwrap()[1] = 255;
65    /// assert_eq!(array, [1, 255, 4, 8]);
66    /// ```
67    pub any Any
68);
69declare_new_fns!(
70    #[crate = crate]
71    ///
72    /// `DynSlice(Mut)<dyn Any>`, `DynSlice(Mut)<dyn Any + Send>` and `DynSlice(Mut)<dyn Any + Send + Sync>` have a few extra methods:
73    /// - [`DynSlice::is`]
74    /// - [`DynSlice::downcast`]
75    /// - [`DynSliceMut::downcast_mut`]
76    ///
77    /// # Examples
78    ///
79    /// ```
80    /// # use dyn_slice::standard::any_send;
81    /// let array: [u8; 4] = [1, 2, 4, 8];
82    /// let slice = any_send::new(&array);
83    ///
84    /// // Assert that the dyn-slice is a slice of `u8`s
85    /// assert!(slice.is::<u8>());
86    /// // Downcast the dyn-slice to a slice of `u8`s
87    /// assert_eq!(slice.downcast::<u8>(), Some(array.as_slice()));
88    /// ```
89    ///
90    /// ```
91    /// # use dyn_slice::standard::any_send;
92    /// let mut array: [u8; 4] = [1, 2, 4, 8];
93    /// let mut slice = any_send::new_mut(&mut array);
94    ///
95    /// // Downcast the mutable dyn-slice to a mutable slice of `u8`s
96    /// slice.downcast_mut::<u8>().unwrap()[1] = 255;
97    /// assert_eq!(array, [1, 255, 4, 8]);
98    /// ```
99    pub any_send Any + Send
100);
101declare_new_fns!(
102    #[crate = crate]
103    ///
104    /// `DynSlice(Mut)<dyn Any>`, `DynSlice(Mut)<dyn Any + Send>` and `DynSlice(Mut)<dyn Any + Send + Sync>` have a few extra methods:
105    /// - [`DynSlice::is`]
106    /// - [`DynSlice::downcast`]
107    /// - [`DynSliceMut::downcast_mut`]
108    ///
109    /// # Examples
110    ///
111    /// ```
112    /// # use dyn_slice::standard::any_sync_send;
113    /// let array: [u8; 4] = [1, 2, 4, 8];
114    /// let slice = any_sync_send::new(&array);
115    ///
116    /// // Assert that the dyn-slice is a slice of `u8`s
117    /// assert!(slice.is::<u8>());
118    /// // Downcast the dyn-slice to a slice of `u8`s
119    /// assert_eq!(slice.downcast::<u8>(), Some(array.as_slice()));
120    /// ```
121    ///
122    /// ```
123    /// # use dyn_slice::standard::any_sync_send;
124    /// let mut array: [u8; 4] = [1, 2, 4, 8];
125    /// let mut slice = any_sync_send::new_mut(&mut array);
126    ///
127    /// // Downcast the mutable dyn-slice to a mutable slice of `u8`s
128    /// slice.downcast_mut::<u8>().unwrap()[1] = 255;
129    /// assert_eq!(array, [1, 255, 4, 8]);
130    /// ```
131    pub any_sync_send Any + Sync + Send
132);
133macro_rules! impl_any_methods {
134    ( $( $t:ty ),* ) => {
135        $(
136            impl<'a> DynSlice<'a, $t> {
137                /// Returns `true` if the underlying slice is of type `T`.
138                #[must_use]
139                pub fn is<T: 'static>(&self) -> bool {
140                    self.get(0).map_or(true, <$t>::is::<T>)
141                }
142
143                /// Returns the underlying slice as `&[T]`, or `None` if the underlying slice is not of type `T`.
144                #[must_use]
145                pub fn downcast<T: 'static>(&self) -> Option<&[T]> {
146                    self.is::<T>().then(|| {
147                        // SAFETY:
148                        // The above line guarantees that the underlying slice is of type `T`,
149                        // so the downcast is valid.
150                        unsafe { self.downcast_unchecked() }
151                    })
152                }
153            }
154
155            impl<'a> DynSliceMut<'a, $t> {
156                /// Returns the underlying slice as `&mut [T]`, or `None` if the underlying slice is not of type `T`.
157                #[must_use]
158                pub fn downcast_mut<T: 'static>(&mut self) -> Option<&mut [T]> {
159                    self.0.is::<T>().then(|| {
160                        // SAFETY:
161                        // The above line guarantees that the underlying slice is of type `T`,
162                        // so the downcast is valid.
163                        unsafe { self.downcast_unchecked_mut() }
164                    })
165                }
166            }
167        )*
168    };
169}
170impl_any_methods!(dyn Any, dyn Any + Send, dyn Any + Sync + Send);
171
172declare_new_fns!(
173    #[crate = crate]
174    pub borrow<Borrowed> Borrow<Borrowed>
175);
176declare_new_fns!(
177    #[crate = crate]
178    pub borrow_mut<Borrowed> BorrowMut<Borrowed>
179);
180
181declare_new_fns!(
182    #[crate = crate]
183    ///
184    /// `DynSlice(Mut)<dyn PartialEq<Rhs>>` implements `PartialEq<[Rhs]>`
185    ///
186    /// # Example
187    /// ```
188    /// # use dyn_slice::standard::partial_eq;
189    /// let array: [u8; 4] = [1, 2, 4, 8];
190    /// let slice = partial_eq::new(&array);
191    ///
192    /// assert!(slice == array.as_slice());
193    /// ```
194    pub partial_eq<Rhs> PartialEq<Rhs>
195);
196impl<'a, Dyn: Pointee<Metadata = DynMetadata<Dyn>> + PartialEq<Rhs> + ?Sized, Rhs> PartialEq<[Rhs]>
197    for DynSlice<'a, Dyn>
198{
199    fn eq(&self, other: &[Rhs]) -> bool {
200        if self.len() != other.len() {
201            return false;
202        }
203
204        self.iter().zip(other.iter()).all(|(a, b)| a == b)
205    }
206}
207impl<'a, Dyn: Pointee<Metadata = DynMetadata<Dyn>> + PartialEq<Rhs> + ?Sized, Rhs> PartialEq<[Rhs]>
208    for DynSliceMut<'a, Dyn>
209{
210    #[inline]
211    fn eq(&self, other: &[Rhs]) -> bool {
212        self.0.eq(other)
213    }
214}
215impl<'a, Dyn: Pointee<Metadata = DynMetadata<Dyn>> + PartialEq<Rhs> + ?Sized, Rhs> PartialEq<&[Rhs]>
216    for DynSlice<'a, Dyn>
217{
218    #[inline]
219    fn eq(&self, other: &&[Rhs]) -> bool {
220        self.eq(*other)
221    }
222}
223impl<'a, Dyn: Pointee<Metadata = DynMetadata<Dyn>> + PartialEq<Rhs> + ?Sized, Rhs> PartialEq<&[Rhs]>
224    for DynSliceMut<'a, Dyn>
225{
226    #[inline]
227    fn eq(&self, other: &&[Rhs]) -> bool {
228        self.0.eq(*other)
229    }
230}
231declare_new_fns!(
232    #[crate = crate]
233    ///
234    /// `DynSlice(Mut)<dyn PartialOrd<Rhs>>` implements `PartialOrd<[Rhs]>`.
235    /// Slices are compared [lexicographically](https://doc.rust-lang.org/stable/std/cmp/trait.Ord.html#lexicographical-comparison).
236    ///
237    /// # Example
238    /// ```
239    /// # use dyn_slice::standard::partial_ord;
240    /// let array: [u8; 4] = [1, 2, 4, 8];
241    /// let slice = partial_ord::new(&array);
242    ///
243    /// assert!(slice > &[1, 2, 3, 4][..]);
244    /// assert!(slice == &array[..]);
245    /// assert!(slice < &[1, 2, 4, 8, 16][..]);
246    /// ```
247    pub partial_ord<Rhs> PartialOrd<Rhs>
248);
249/// Implements comparison of slices [lexicographically](https://doc.rust-lang.org/stable/std/cmp/trait.Ord.html#lexicographical-comparison).
250impl<'a, Dyn: Pointee<Metadata = DynMetadata<Dyn>> + PartialOrd<Rhs> + ?Sized, Rhs>
251    PartialOrd<[Rhs]> for DynSlice<'a, Dyn>
252{
253    fn partial_cmp(&self, other: &[Rhs]) -> Option<Ordering> {
254        let mut i1 = self.iter();
255        let mut i2 = other.iter();
256
257        loop {
258            return Some(match (i1.next(), i2.next()) {
259                (Some(a), Some(b)) => match a.partial_cmp(b)? {
260                    Ordering::Equal => continue,
261                    order => order,
262                },
263                (Some(_), None) => Ordering::Greater,
264                (None, Some(_)) => Ordering::Less,
265                (None, None) => Ordering::Equal,
266            });
267        }
268    }
269}
270/// Implements comparison of slices [lexicographically](https://doc.rust-lang.org/stable/std/cmp/trait.Ord.html#lexicographical-comparison).
271impl<'a, Dyn: Pointee<Metadata = DynMetadata<Dyn>> + PartialOrd<Rhs> + ?Sized, Rhs>
272    PartialOrd<[Rhs]> for DynSliceMut<'a, Dyn>
273{
274    #[inline]
275    fn partial_cmp(&self, other: &[Rhs]) -> Option<Ordering> {
276        self.0.partial_cmp(other)
277    }
278}
279/// Implements comparison of slices [lexicographically](https://doc.rust-lang.org/stable/std/cmp/trait.Ord.html#lexicographical-comparison).
280impl<'a, Dyn: Pointee<Metadata = DynMetadata<Dyn>> + PartialOrd<Rhs> + ?Sized, Rhs>
281    PartialOrd<&[Rhs]> for DynSlice<'a, Dyn>
282{
283    #[inline]
284    fn partial_cmp(&self, other: &&[Rhs]) -> Option<Ordering> {
285        self.partial_cmp(*other)
286    }
287}
288/// Implements comparison of slices [lexicographically](https://doc.rust-lang.org/stable/std/cmp/trait.Ord.html#lexicographical-comparison).
289impl<'a, Dyn: Pointee<Metadata = DynMetadata<Dyn>> + PartialOrd<Rhs> + ?Sized, Rhs>
290    PartialOrd<&[Rhs]> for DynSliceMut<'a, Dyn>
291{
292    #[inline]
293    fn partial_cmp(&self, other: &&[Rhs]) -> Option<Ordering> {
294        self.0.partial_cmp(*other)
295    }
296}
297
298declare_new_fns!(
299    #[crate = crate]
300    pub as_ref<T> AsRef<T>
301);
302declare_new_fns!(
303    #[crate = crate]
304    pub as_mut<T> AsMut<T>
305);
306
307declare_new_fns!(
308    #[crate = crate]
309    pub binary Binary
310);
311declare_new_fns!(
312    #[crate = crate]
313    ///
314    /// # Example
315    /// ```
316    /// # use dyn_slice::standard::debug;
317    /// let array: [u8; 4] = [1, 2, 4, 8];
318    /// let slice = debug::new(&array);
319    ///
320    /// assert_eq!(
321    ///     format!("{slice:?}"),
322    ///     "[1, 2, 4, 8]",
323    /// );
324    /// ```
325    pub debug Debug
326);
327impl<'a, Dyn: Pointee<Metadata = DynMetadata<Dyn>> + Debug + ?Sized> Debug for DynSlice<'a, Dyn> {
328    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
329        f.debug_list().entries(self.iter()).finish()
330    }
331}
332impl<'a, Dyn: Pointee<Metadata = DynMetadata<Dyn>> + Debug + ?Sized> Debug
333    for DynSliceMut<'a, Dyn>
334{
335    #[inline]
336    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
337        <DynSlice<Dyn> as Debug>::fmt(&self.0, f)
338    }
339}
340declare_new_fns!(
341    #[crate = crate]
342    pub display Display
343);
344declare_new_fns!(
345    #[crate = crate]
346    pub lower_exp LowerExp
347);
348declare_new_fns!(
349    #[crate = crate]
350    pub lower_hex LowerHex
351);
352declare_new_fns!(
353    #[crate = crate]
354    pub octal Octal
355);
356declare_new_fns!(
357    #[crate = crate]
358    pub pointer Pointer
359);
360impl<'a, Dyn: Pointee<Metadata = DynMetadata<Dyn>> + ?Sized> Pointer for DynSlice<'a, Dyn> {
361    #[inline]
362    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
363        <*const () as Pointer>::fmt(&self.data, f)
364    }
365}
366impl<'a, Dyn: Pointee<Metadata = DynMetadata<Dyn>> + ?Sized> Pointer for DynSliceMut<'a, Dyn> {
367    #[inline]
368    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
369        <*const () as Pointer>::fmt(&self.data, f)
370    }
371}
372declare_new_fns!(
373    #[crate = crate]
374    pub upper_exp UpperExp
375);
376declare_new_fns!(
377    #[crate = crate]
378    pub upper_hex UpperHex
379);
380declare_new_fns!(
381    #[crate = crate]
382    pub write Write
383);
384
385declare_new_fns!(
386    #[crate = crate]
387    pub future<Output> Future<Output = Output>
388);
389
390declare_new_fns!(
391    #[crate = crate]
392    pub build_hasher<Hasher: hash::Hasher> BuildHasher<Hasher = Hasher>
393);
394declare_new_fns!(
395    #[crate = crate]
396    pub hasher Hasher
397);
398
399declare_new_fns!(
400    #[crate = crate]
401    ///
402    /// # Example
403    /// ```
404    /// # use dyn_slice::standard::double_ended_iterator;
405    /// let mut array = [[1, 2].into_iter(), [3, 4].into_iter(), [5, 6].into_iter()];
406    /// let mut slice = double_ended_iterator::new_mut(&mut array);
407    /// let mut iter = slice.iter_mut().flatten();
408    ///
409    /// assert_eq!(iter.next_back().unwrap(), 6);
410    /// assert_eq!(iter.next_back().unwrap(), 5);
411    /// assert_eq!(iter.next_back().unwrap(), 4);
412    /// assert_eq!(iter.next_back().unwrap(), 3);
413    /// assert_eq!(iter.next_back().unwrap(), 2);
414    /// assert_eq!(iter.next_back().unwrap(), 1);
415    /// ```
416    pub double_ended_iterator<Item> DoubleEndedIterator<Item = Item>
417);
418declare_new_fns!(
419    #[crate = crate]
420    pub exact_size_iterator<Item> ExactSizeIterator<Item = Item>
421);
422declare_new_fns!(
423    #[crate = crate]
424    pub fused_iterator<Item> FusedIterator<Item = Item>
425);
426declare_new_fns!(
427    #[crate = crate]
428    ///
429    /// # Examples
430    ///
431    /// ```
432    /// # use dyn_slice::standard::iterator;
433    /// let mut array = [(1..5), (2..9), (4..6)];
434    /// let mut slice = iterator::new_mut(&mut array);
435    ///
436    /// assert_eq!(slice[0].next(), Some(1));
437    /// assert_eq!(slice[1].next(), Some(2));
438    /// assert_eq!(slice[2].next(), Some(4));
439    ///
440    /// assert_eq!(slice[0].next(), Some(2));
441    /// ```
442    ///
443    /// ```
444    /// # use dyn_slice::standard::iterator;
445    /// let mut array = [[1, 2].into_iter(), [3, 4].into_iter(), [5, 6].into_iter()];
446    /// let mut slice = iterator::new_mut(&mut array);
447    /// let mut iter = slice.iter_mut().flatten();
448    ///
449    /// assert_eq!(iter.next().unwrap(), 1);
450    /// assert_eq!(iter.next().unwrap(), 2);
451    /// assert_eq!(iter.next().unwrap(), 3);
452    /// assert_eq!(iter.next().unwrap(), 4);
453    /// assert_eq!(iter.next().unwrap(), 5);
454    /// assert_eq!(iter.next().unwrap(), 6);
455    /// ```
456    pub iterator<Item> Iterator<Item = Item>
457);
458
459declare_new_fns!(
460    #[crate = crate]
461    pub add_assign<Rhs> AddAssign<Rhs>
462);
463declare_new_fns!(
464    #[crate = crate]
465    pub bit_and_assign<Rhs> BitAndAssign<Rhs>
466);
467declare_new_fns!(
468    #[crate = crate]
469    pub bit_or_assign<Rhs> BitOrAssign<Rhs>
470);
471declare_new_fns!(
472    #[crate = crate]
473    pub bit_xor_assign<Rhs> BitXorAssign<Rhs>
474);
475declare_new_fns!(
476    #[crate = crate]
477    pub deref<Target> Deref<Target = Target>
478);
479declare_new_fns!(
480    #[crate = crate]
481    pub deref_mut<Target> DerefMut<Target = Target>
482);
483declare_new_fns!(
484    #[crate = crate]
485    pub div_assign<Rhs> DivAssign<Rhs>
486);
487declare_new_fns!(
488    #[crate = crate]
489    pub index<Idx: ?Sized, Output: ?Sized> Index<Idx, Output = Output>
490);
491declare_new_fns!(
492    #[crate = crate]
493    pub index_mut<Idx: ?Sized, Output: ?Sized> IndexMut<Idx, Output = Output>
494);
495declare_new_fns!(
496    #[crate = crate]
497    pub mul_assign<Rhs> MulAssign<Rhs>
498);
499declare_new_fns!(
500    #[crate = crate]
501    pub rem_assign<Rhs> RemAssign<Rhs>
502);
503declare_new_fns!(
504    #[crate = crate]
505    pub shl_assign<Rhs> ShlAssign<Rhs>
506);
507declare_new_fns!(
508    #[crate = crate]
509    pub shr_assign<Rhs> ShrAssign<Rhs>
510);
511declare_new_fns!(
512    #[crate = crate]
513    pub sub_assign<Rhs> SubAssign<Rhs>
514);
515
516/// A reference-to-value conversion.
517pub trait To<T> {
518    /// Converts this reference into the (usually inferred) input type.
519    fn to(&self) -> T;
520}
521
522// From implies Into, so Into is used to include both traits
523impl<T, F: Into<T> + Copy> To<T> for F {
524    #[inline]
525    fn to(&self) -> T {
526        (*self).into()
527    }
528}
529
530declare_new_fns!(
531    #[crate = crate]
532    pub to<T> To<T>
533);
534
535#[cfg(feature = "alloc")]
536mod standard_alloc {
537    extern crate alloc;
538    use alloc::string::ToString;
539
540    use crate::declare_new_fns;
541
542    declare_new_fns!(
543        #[crate = crate]
544        #[cfg_attr(doc, doc(cfg(feature = "alloc")))]
545        #[doc = feature_availability!("alloc")]
546        pub to_string ToString
547    );
548}
549#[cfg(feature = "alloc")]
550pub use standard_alloc::*;
551
552#[cfg(feature = "std")]
553mod standard_std {
554    use std::{
555        error::Error,
556        io::{BufRead, IsTerminal, Read, Seek, Write},
557        net::ToSocketAddrs,
558    };
559
560    use crate::declare_new_fns;
561
562    declare_new_fns!(
563        #[crate = crate]
564        #[cfg_attr(doc, doc(cfg(feature = "std")))]
565        #[doc = feature_availability!("std")]
566        pub error Error
567    );
568
569    declare_new_fns!(
570        #[crate = crate]
571        #[cfg_attr(doc, doc(cfg(feature = "std")))]
572        #[doc = feature_availability!("std")]
573        pub buf_read BufRead
574    );
575    declare_new_fns!(
576        #[crate = crate]
577        #[cfg_attr(doc, doc(cfg(feature = "std")))]
578        #[doc = feature_availability!("std")]
579        pub is_terminal IsTerminal
580    );
581    declare_new_fns!(
582        #[crate = crate]
583        #[cfg_attr(doc, doc(cfg(feature = "std")))]
584        #[doc = feature_availability!("std")]
585        pub io_read Read
586    );
587    declare_new_fns!(
588        #[crate = crate]
589        #[cfg_attr(doc, doc(cfg(feature = "std")))]
590        #[doc = feature_availability!("std")]
591        pub seek Seek
592    );
593    declare_new_fns!(
594        #[crate = crate]
595        #[cfg_attr(doc, doc(cfg(feature = "std")))]
596        #[doc = feature_availability!("std")]
597        pub io_write Write
598    );
599
600    declare_new_fns!(
601        #[crate = crate]
602        #[cfg_attr(doc, doc(cfg(feature = "std")))]
603        #[doc = feature_availability!("std")]
604        pub to_socket_addrs<Iter: core::iter::Iterator<Item = std::net::SocketAddr>>
605            ToSocketAddrs<Iter = Iter>
606    );
607}
608#[cfg(feature = "std")]
609pub use standard_std::*;
610
611#[cfg(test)]
612mod test {
613    use super::*;
614
615    #[test]
616    fn test_any() {
617        #[derive(Debug, PartialEq)]
618        struct A;
619
620        let array = [A, A];
621        let slice = any::new(&array);
622
623        assert!(slice.is::<A>());
624        assert!(!slice.is::<u8>());
625
626        assert_eq!(slice.downcast::<A>(), Some(&array[..]));
627        assert_eq!(slice.downcast::<u8>(), None);
628
629        // Using for loop rather than iter to make sure exactly 2 elements are
630        // checked, without trusting iter
631        for i in 0..array.len() {
632            assert!(slice.get(i).expect("expected an element").is::<A>());
633        }
634
635        // Make sure the slice can be downcast to anything when empty
636
637        let array: [A; 0] = [];
638        let slice = any::new(&array);
639
640        assert!(slice.is::<A>());
641        assert!(slice.is::<u8>());
642
643        assert_eq!(slice.downcast::<A>(), Some(&array[..]));
644        assert_eq!(slice.downcast::<u8>(), Some(&[][..]));
645    }
646
647    #[test]
648    fn test_borrow() {
649        let a: Box<u8> = Box::new(5);
650        let b: Box<u8> = Box::new(7);
651
652        let array = [a, b];
653        let slice = borrow::new::<u8, _>(&array);
654
655        for (i, y) in array.iter().enumerate() {
656            assert_eq!(slice.get(i).expect("expected an element").borrow(), &**y);
657        }
658    }
659
660    #[test]
661    fn test_partial_eq() {
662        let array: [u8; 2] = [5, 7];
663        let slice = partial_eq::new::<u8, _>(&array);
664
665        for (i, y) in array.iter().enumerate() {
666            let element = slice.get(i).expect("expected an element");
667            assert!(element == y);
668            assert!(element != &200);
669        }
670    }
671
672    #[test]
673    fn test_partial_eq_impl() {
674        let s: &[u8] = &[10, 11, 12];
675        let slice = partial_eq::new::<u8, _>(s);
676
677        let ne1: &[u8] = &[10, 11, 22];
678        let ne2: &[u8] = &[10, 21, 12];
679        let ne3: &[u8] = &[20, 11, 12];
680        let ne4: &[u8] = &[10, 11, 12, 13];
681        let ne5: &[u8] = &[10, 11];
682        let ne6: &[u8] = &[10];
683        let ne7: &[u8] = &[];
684
685        assert!(slice == s);
686
687        assert!(slice != ne1);
688        assert!(slice != ne2);
689        assert!(slice != ne3);
690        assert!(slice != ne4);
691        assert!(slice != ne5);
692        assert!(slice != ne6);
693        assert!(slice != ne7);
694    }
695
696    #[test]
697    fn test_partial_ord() {
698        let array: [u8; 2] = [5, 7];
699        let slice = partial_ord::new::<u8, _>(&array);
700
701        for (i, y) in array.iter().enumerate() {
702            let element = slice.get(i).expect("expected an element");
703            assert!(element > &3);
704            assert!(element == y);
705            assert!(element < &10);
706        }
707    }
708
709    #[test]
710    fn test_partial_ord_impl() {
711        let s: &[u8] = &[10, 11, 12];
712        let slice = partial_ord::new::<u8, _>(s);
713
714        let l1: &[u8] = &[10, 11, 2];
715        let l2: &[u8] = &[10, 1, 12];
716        let l3: &[u8] = &[0, 11, 12];
717        let l4: &[u8] = &[10, 11, 2, 3];
718        let l5: &[u8] = &[10, 1, 12, 3];
719        let l6: &[u8] = &[0, 11, 12, 3];
720        let l7: &[u8] = &[10, 11];
721        let l8: &[u8] = &[10];
722        let l9: &[u8] = &[];
723
724        let g1: &[u8] = &[10, 11, 22];
725        let g2: &[u8] = &[10, 21, 12];
726        let g3: &[u8] = &[20, 11, 12];
727        let g4: &[u8] = &[10, 21];
728        let g5: &[u8] = &[20];
729        let g6: &[u8] = &[10, 11, 12, 3];
730
731        assert_eq!(slice.partial_cmp(s), Some(Ordering::Equal));
732
733        assert!(s > l1);
734        assert!(s > l2);
735        assert!(s > l3);
736        assert!(s > l4);
737        assert!(s > l5);
738        assert!(s > l6);
739        assert!(s > l7);
740        assert!(s > l8);
741        assert!(s > l9);
742
743        assert!(s < g1);
744        assert!(s < g2);
745        assert!(s < g3);
746        assert!(s < g4);
747        assert!(s < g5);
748        assert!(s < g6);
749    }
750
751    #[test]
752    fn test_as_ref() {
753        let a: Box<u8> = Box::new(5);
754        let b: Box<u8> = Box::new(7);
755
756        let array = [a, b];
757        let slice = as_ref::new::<u8, _>(&array);
758
759        for (i, y) in array.iter().enumerate() {
760            assert_eq!(slice.get(i).expect("expected an element").as_ref(), &**y);
761        }
762    }
763
764    #[test]
765    fn test_debug() {
766        #[derive(Debug)]
767        struct A;
768        let debugged = format!("{A:?}");
769
770        let array = [A, A];
771        let slice = debug::new(&array);
772
773        for i in 0..array.len() {
774            let element = slice.get(i).expect("expected an element");
775            assert_eq!(format!("{element:?}"), debugged);
776        }
777
778        assert_eq!(format!("{slice:?}"), format!("{array:?}"));
779
780        let slice = debug::new::<A>(&[]);
781        assert_eq!(format!("{slice:?}"), "[]");
782
783        let array = [A];
784        let slice = debug::new(&array);
785        assert_eq!(format!("{slice:?}"), format!("{array:?}"));
786    }
787
788    #[test]
789    fn test_display() {
790        struct A;
791        impl fmt::Display for A {
792            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
793                write!(f, "A displayed")
794            }
795        }
796        let displayed = format!("{A}");
797
798        let array = [A, A];
799        let slice = display::new(&array);
800
801        for i in 0..array.len() {
802            let element = slice.get(i).expect("expected an element");
803            assert_eq!(format!("{element}"), displayed);
804        }
805    }
806
807    #[test]
808    fn test_hasher() {
809        use std::collections::hash_map::DefaultHasher;
810
811        const TEST_DATA: &[u8] = b"test hash data";
812
813        let mut reference = DefaultHasher::new();
814        reference.write(TEST_DATA);
815        let reference = reference.finish();
816
817        let mut array = [DefaultHasher::new(), DefaultHasher::new()];
818        let mut slice = hasher::new_mut(&mut array);
819
820        for hasher in &mut slice {
821            hasher.write(TEST_DATA);
822
823            assert_eq!(hasher.finish(), reference);
824        }
825    }
826
827    #[test]
828    fn test_iterator() {
829        let mut array = [(0..5), (10..15), (-30..-25)];
830        let mut slice = iterator::new_mut(&mut array);
831
832        for (range, expected) in slice.iter_mut().zip([0, 10, -30]) {
833            assert_eq!(range.next(), Some(expected));
834        }
835
836        for (range, expected) in slice.iter_mut().zip([1, 11, -29]) {
837            assert_eq!(range.next(), Some(expected));
838        }
839    }
840
841    #[test]
842    fn test_to() {
843        use core::num::NonZeroU8;
844
845        let a: u8 = 5;
846        let b: u8 = <u8 as To<u8>>::to(&a);
847
848        assert_eq!(a, b);
849
850        let b: u16 = <u8 as To<u16>>::to(&a);
851        let a: u16 = a.into();
852
853        assert_eq!(a, b);
854
855        let array: [NonZeroU8; 2] = {
856            // SAFETY:
857            // NonZeroU8 has the same layout as u8, and can therefore be transmuted.
858            unsafe { [NonZeroU8::new_unchecked(5), NonZeroU8::new_unchecked(7)] }
859        };
860        let slice = to::new::<u8, _>(&array);
861
862        for (i, y) in array.iter().enumerate() {
863            let element = slice.get(i).expect("expected an element");
864            assert_eq!(element.to(), y.get());
865        }
866    }
867
868    #[test]
869    fn test_to_string() {
870        struct A;
871        impl core::fmt::Display for A {
872            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
873                write!(f, "A displayed")
874            }
875        }
876        let displayed = A.to_string();
877
878        let array = [A, A];
879        let slice = to_string::new(&array);
880
881        for i in 0..array.len() {
882            let element = slice.get(i).expect("expected an element");
883            assert_eq!(element.to_string(), displayed);
884        }
885    }
886
887    #[test]
888    fn test_error() {
889        #[derive(Debug)]
890        struct A;
891        impl fmt::Display for A {
892            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
893                write!(f, "A displayed")
894            }
895        }
896        impl std::error::Error for A {}
897        let displayed = format!("{A}");
898
899        let array = [A, A];
900        let slice = error::new(&array);
901
902        for i in 0..array.len() {
903            let element = slice.get(i).expect("expected an element");
904            assert_eq!(format!("{element}"), displayed);
905        }
906
907        assert_eq!(format!("{slice:?}"), format!("{array:?}"));
908    }
909}