default_params 1.1.0

Default parameters can be useful
Documentation
#![no_std]
//#![feature(adt_const_params)]
#![warn(clippy::pedantic,clippy::cargo,clippy::nursery,clippy::complexity,clippy::perf,clippy::correctness,clippy::all)]
#![warn(clippy::cognitive_complexity,clippy::large_const_arrays)]
#![warn(clippy::style,clippy::suspicious,large_assignments)]
#![warn(rustdoc::all,missing_docs,clippy::empty_docs)]
//! Do you want default function arguments or method parameters inside Rust?
//! 
//! Well, too bad! As this feature is currently not supported in Rust we can
//! only emulate this functionality through macros and even more macros.
//! 
//! # Formalisation
//! Default parameters could be easily formalised as
//! ```ignore
//! struct DefaultParam<T, const VAL: T>(T);
//! ```
//! 
//! # Reality
//! This approach however falls apart in a spectacular fashion as Rust doesn't
//! support types dependent on other types.
//! 
//! Sadly this leaves us no choice. We can currently only make default arguments
//! for `integer`, `bool` and `char` types.
//! 
//! # How does this implementation work?
//! - All supported types have a wrapper around them (`i32 -> Di32`, `bool -> Dbool` ...)
//! - Empty default arguments can be created via 
//! ```
//! # use default_params::Di32;
//! let def1=Di32::<23>::new(); // Its value will be 23
//! ```
//! - Default arguments with values can be created via
//! ```
//! # use default_params::Di32;
//! let def2=Di32::<5>::from(53); // Its value will be 53
//! ```
//! - The value of default arguments can be unwrapped via
//! ```
//! # use default_params::Di32;
//! # let def1=Di32::<23>::new();
//! # let def2=Di32::<5>::from(53);
//! assert_eq!(def1.unwrap(),23);
//! assert_eq!(def2.unwrap(),53);
//! ```

/// Trait for classifying default parameters
pub trait DefaultParam<T> : From<T> + Default {
    /// Unwrap a default parameter into a primitive value
    /// 
    /// # Example
    /// ```
    /// # use default_params::Di32;
    /// let def=Di32::<23>::new();
    /// assert_eq!(def.unwrap(),23)
    /// ```
    #[must_use]
    fn unwrap(self) -> T;
    /// Create a new Default parameter
    /// 
    /// # Example
    /// ```
    /// # use default_params::Di32;
    /// let def=Di32::<23>::new();
    /// assert_eq!(def.unwrap(),23)
    /// ```
    #[must_use]
    fn new() -> Self;
}

macro_rules! gen_default_param {
    ($name:ident, $type:ty) => {
        /// Default parameter for primitive type
        pub struct $name<const VAL: $type>(pub $type);

        impl<const VAL: $type> $name<VAL> {
            /// Unwrap a default parameter into a primitive value
            /// 
            /// # Example
            /// ```
            /// # use default_params::Di32;
            /// let def=Di32::<23>::new();
            /// assert_eq!(def.unwrap(),23)
            /// ```
            #[must_use]
            pub const fn const_unwrap(self) -> $type {
                self.0
            }
            /// Create a new Default parameter
            /// 
            /// # Example
            /// ```
            /// # use default_params::Di32;
            /// let def=Di32::<23>::new();
            /// assert_eq!(def.unwrap(),23)
            /// ```
            #[must_use]
            pub const fn const_new() -> Self {
                Self(VAL)
            }
        }
        impl<const VAL: $type> DefaultParam<$type> for $name<VAL> {
            fn unwrap(self) -> $type {
                self.0
            }
            fn new() -> Self {
                Self(VAL)
            }
        }
        impl<const VAL: $type> From<$type> for $name<VAL> {
            fn from(value: $type) -> Self {
                Self(value)
            }
        }
        impl<const VAL: $type> Default for $name<VAL> {
            fn default() -> Self {
                Self::new()
            }
        }
    };
}

gen_default_param!(Di8,i8);
gen_default_param!(Di16,i16);
gen_default_param!(Di32,i32);
gen_default_param!(Di64,i64);
gen_default_param!(Di128,i128);
gen_default_param!(Disize,isize);
gen_default_param!(Du8,u8);
gen_default_param!(Du16,u16);
gen_default_param!(Du32,u32);
gen_default_param!(Du64,u64);
gen_default_param!(Du128,u128);
gen_default_param!(Dusize,usize);
gen_default_param!(Dbool,bool);
gen_default_param!(Dchar,char);