extra-default 0.2.0

Extra traits to go along with the Default trait.
Documentation
//! This crate provides additional `Default` traits which are most useful for slices and strings.
//!
//! * [`DefaultRef`] is imiplemented for `for<'a> &'a Self: Default`.
//! * [`DefaultBox`] is imiplemented for `Box<Self>: Default`.
//! * [`DefaultOwned`] is imiplemented for `<Self as ToOwned>::Owned: Default`.
//!
//! [`DefaultRef`]: trait.DefaultRef.html
//! [`DefaultBox`]: trait.DefaultBox.html
//! [`DefaultOwned`]: trait.DefaultOwned.html
#![cfg_attr(all(not(feature = "std"), feature = "collections"), feature(collections))]
#![cfg_attr(all(not(feature = "collections"), feature = "alloc"), feature(alloc))]
#![cfg_attr(not(feature = "std"), no_std)]
#![doc(html_root_url = "https://docs.charr.xyz/extra-default/")]
#![deny(warnings)]

#[cfg(all(not(feature = "std"), feature = "collections"))]
extern crate collections;

#[cfg(all(not(feature = "collections"), feature = "alloc"))]
extern crate alloc;

/// Allows creating a default reference to a type.
pub trait DefaultRef {
    /// Creates a reasonable default reference for this type.
    fn default_ref<'a>() -> &'a Self;
}
impl<T: ?Sized> DefaultRef for T
    where for<'a> &'a T: Default
{
    fn default_ref<'a>() -> &'a Self {
        Default::default()
    }
}

#[cfg(feature = "alloc")]
mod boxed {
    #[cfg(not(feature = "collections"))]
    use alloc::boxed::Box;
    #[cfg(all(not(feature = "std"), feature = "collections"))]
    use collections::boxed::Box;

    /// Allows creating a default box of a type.
    pub trait DefaultBox {
        /// Creates a reasonable default box of this type.
        fn default_box() -> Box<Self>;
    }
    impl<T: ?Sized> DefaultBox for T
        where Box<T>: Default
    {
        fn default_box() -> Box<Self> {
            Default::default()
        }
    }
}
#[cfg(feature = "alloc")]
pub use self::boxed::DefaultBox;

#[cfg(feature = "collections")]
mod owned {
    #[cfg(feature = "std")]
    use std::borrow::Borrow;

    #[cfg(not(feature = "std"))]
    use collections::borrow::{Borrow, ToOwned};


    /// Allows creating a default owned version of a type.
    pub trait DefaultOwned: ToOwned {
        /// Creates a reasonable, owned default of this type.
        fn default_owned() -> <Self as ToOwned>::Owned;
    }
    impl<O: Default + Borrow<T>, T: ?Sized + ToOwned<Owned = O>> DefaultOwned
        for T {
        fn default_owned() -> <Self as ToOwned>::Owned {
            Default::default()
        }
    }
}
#[cfg(feature = "collections")]
pub use self::owned::DefaultOwned;


#[cfg(test)]
mod tests {
    use super::DefaultRef;

    #[test]
    fn str_ref() {
        let s: &str = str::default_ref();
        assert_eq!(s, "");
    }

    #[test]
    fn byte_slice() {
        let s: &[u8] = <[u8]>::default_ref();
        assert_eq!(s, &[]);
    }

    #[test]
    fn float_slice() {
        let s: &[f64] = <[f64]>::default_ref();
        assert_eq!(s, &[]);
    }

    #[cfg(feature = "alloc")]
    mod alloc {
        use super::super::DefaultBox;

        #[cfg(not(feature = "collections"))]
        use alloc::boxed::Box;
        #[cfg(all(feature = "collections", not(feature = "std")))]
        use collections::boxed::Box;

        #[test]
        fn str_box() {
            let s: Box<str> = str::default_box();
            assert_eq!(&*s, "");
        }

        #[cfg(feature = "alloc")]
        #[test]
        fn byte_box() {
            let s: Box<[u8]> = <[u8]>::default_box();
            assert_eq!(&*s, &[]);
        }

        #[cfg(feature = "alloc")]
        #[test]
        fn float_box() {
            let s: Box<[f64]> = <[f64]>::default_box();
            assert_eq!(&*s, &[]);
        }
    }

    #[cfg(feature = "collections")]
    mod collections {
        use super::super::DefaultOwned;

        #[cfg(all(feature = "collections", not(feature = "std")))]
        use collections::{Vec, String};

        #[test]
        fn string() {
            let s: String = str::default_owned();
            assert_eq!(&*s, "");
        }

        #[test]
        fn byte_vec() {
            let s: Vec<u8> = <[u8]>::default_owned();
            assert_eq!(&*s, &[])
        }

        #[test]
        fn float_vec() {
            let s: Vec<f64> = <[f64]>::default_owned();
            assert_eq!(&*s, &[]);
        }
    }
}