core_extensions/macros/const_default.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
/// Gets the [`ConstDefault::DEFAULT`](trait.ConstDefault.html#associatedconstant.DEFAULT)
/// associated constant for a type.
///
/// Use this macro to avoid accidentally using inherent `DEFAULT` associated cosntants.
///
/// # Argument
///
/// If a type is passed (ie: `const_default!(Foo)`),
/// this gets its [`ConstDefault::DEFAULT`] associated constant.
///
/// If nothing is passed (ie: `const_default!()`),
/// this is equivalent to [`ConstDefault::DEFAULT`],
/// inferring the type it gets the default value of.
///
/// # Examples
///
/// ### Basic
///
/// ```rust
/// use core_extensions::const_default;
///
/// assert_eq!(const_default!(u32), 0);
/// assert_eq!(const_default!(bool), false);
/// assert_eq!(const_default!((bool, Option<u32>)), (false, None));
#[cfg_attr(
feature = "alloc",
doc = "assert_eq!(const_default!(([u32; 0], Vec<u32>)), ([], Vec::new()));"
)]
///
/// let list: &[u8] = const_default!();
/// assert!(list.is_empty());
///
/// let string: &str = const_default!();
/// assert!(string.is_empty());
///
/// ```
///
/// ### Implementing `ConstDefault`
///
/// ```rust
/// use core_extensions::{ConstDefault, const_default};
///
/// #[derive(Debug, PartialEq)]
/// struct Foo<T> {
/// foo: u32,
/// bar: Option<T>,
/// }
///
/// impl<T> ConstDefault for Foo<T> {
/// const DEFAULT: Self = Self {
/// foo: const_default!(),
/// bar: const_default!(),
/// };
/// }
///
/// let expected = Foo{foo: 0, bar: None};
/// assert_eq!(const_default!(Foo<u32>), expected);
/// assert_eq!(Foo::<u32>::DEFAULT, expected);
///
///
/// ```
///
/// ### Inherent `DEFAULT` associated constant
///
/// This demonstrates how inherent associated constants have priority over
/// trait associated constants.
///
/// ```rust
/// use core_extensions::{ConstDefault, const_default};
///
/// #[derive(Debug, PartialEq)]
/// struct Foo(u32);
///
/// impl ConstDefault for Foo {
/// const DEFAULT: Self = Foo(0);
/// }
///
/// impl Foo {
/// const DEFAULT: Self = Foo(3333);
/// }
///
/// assert_eq!(const_default!(Foo), Foo(0));
/// assert_eq!(<Foo as ConstDefault>::DEFAULT, Foo(0));
/// assert_eq!(Foo::DEFAULT, Foo(3333));
///
/// ```
///
/// [`ConstDefault::DEFAULT`]: trait.ConstDefault.html#associatedconstant.DEFAULT
#[cfg(feature = "const_default")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "const_default")))]
#[macro_export]
macro_rules! const_default {
() => {
$crate::ConstDefault::DEFAULT
};
($This:ty) => {
<$This as $crate::ConstDefault>::DEFAULT
};
}