/// Derives the [`ConstDefault`] trait for structs and enums. /// /// [For examples look here](#examples) /// /// For enums, this requires a `#[cdef(default)]` attribute on exactly one variant. /// /// # Default behavior /// /// By default, this derive macro generates a [`ConstDefault`] impl with: /// - [`ConstDefault`] bounds on all type parameters. /// - [`ConstDefault::DEFAULT`] as the value of all the fields. /// /// # Attributes /// /// ### Container attributes /// /// Attributes used above the type definition. /// /// `#[cdef(crate = foo::bar)]`([example](#crate-example)):
/// Replaces the path to `core_extensions` with `foo::bar` /// /// `#[cdef(bound(T: Foo + Bar))]`([example](#bound-example)):
/// Replaces the default bound (`ConstDefault`) of the T type parameter with /// the passed-in bounds.
/// `#[cdef(bound(T: ))]` is allowed. /// /// `#[cdef(no_bounds)]`([example](#no_bounds-example)):
/// Removes the `ConstDefault` bound for all type parameters /// /// `#[cdef(field_bound)]`([example](#field_bound-example)):
/// Removes the `ConstDefault` bound for type parameters, /// replacing them with `ConstDefault` bounds on all of the field types. /// /// `#[cdef(where T: Foo + Bar)]`([example](#where-example)):
/// Adds arbitrary bounds to the `ConstDefault` impl. /// /// `#[cdef(debug_print)]`:
/// For diagnostics, causes the derive macro to panic with the code generated by it. /// /// ### Variant attributes /// /// `#[cdef(default)]`([example](#basic-enum-example)):
/// Uses that variant for the default value. /// This must be used on exactly one variant. /// /// ### Field attributes /// /// `#[cdef(default = )]`([example](#default-value-example)):
/// Replaces the default value of the field ([`ConstDefault::DEFAULT`]) with ``, /// which must be usable in a const context. /// /// `#[cdef(field_bound)]`([example](#field_bound_field-example)):
/// Adds a [`ConstDefault`] bound for the field type. /// /// # Examples /// /// ### Basic struct /// /// ```rust /// use core_extensions::ConstDefault; /// /// #[derive(Debug, PartialEq, ConstDefault)] /// struct Foo { /// bar: T, /// baz: Option, /// } /// /// const DEF: Foo<[bool; 2]> = Foo::DEFAULT; /// assert_eq!(DEF, Foo{bar: [false, false], baz: None}); /// /// assert_eq!(Foo{bar: "", baz: None}, ConstDefault::DEFAULT); /// /// ``` /// /// /// ### Basic enum /// /// ```rust /// use core_extensions::ConstDefault; /// /// #[derive(Debug, PartialEq, ConstDefault)] /// enum Foo { /// Bar(u32), /// #[cdef(default)] /// Baz(Option), /// } /// /// const DEF: Foo = ConstDefault::DEFAULT; /// assert_eq!(DEF, Foo::Baz(None)); /// /// assert_eq!(Foo::DEFAULT, Foo::Baz(None)); /// /// ``` /// /// /// ### Crate renaming /// /// This example demonstrates how the `core_extensions` crate can be renamed, /// passing the new name to the derive macro. /// /// ```rust /// # extern crate core_extensions as cext; /// # extern crate std as core_extensions; /// # /// use cext::ConstDefault; /// /// #[derive(Debug, PartialEq, ConstDefault)] /// #[cdef(crate = cext)] /// struct Foo { /// bar: u32, /// baz: Option, /// } /// /// # fn main() { /// assert_eq!(Foo::DEFAULT, Foo{bar: 0, baz: None}); /// # } /// ``` /// /// /// ### Different default value /// /// This example demonstrates replacing the default value for one field. /// The assigned expression can be anything, so long as it's usable in a const context. /// /// ```rust /// use core_extensions::ConstDefault; /// /// #[derive(Debug, PartialEq, ConstDefault)] /// struct Foo { /// #[cdef(default = power(5))] /// bar: u32, /// baz: Option, /// } /// /// const fn power(n: u32) -> u32 { /// 1 << n /// } /// /// assert_eq!(Foo::DEFAULT, Foo{bar: 32, baz: None}); /// ``` /// /// /// ### No Bounds /// /// This example demonstrates removing the default `ConstDefault` bound on all type parameters. /// /// ```rust /// use core_extensions::ConstDefault; /// /// use std::cmp::Ordering; /// use std::marker::PhantomData; /// /// #[derive(Debug, PartialEq)] /// struct NoDefault(T); /// /// /// #[derive(Debug, PartialEq, ConstDefault)] /// // removes the default `ConstDefault` bound on all type parameters /// #[cdef(no_bounds)] /// struct NoBounds { /// bar: Option, /// baz: PhantomData, /// qux: &'static [V], /// } /// /// assert_eq!( /// NoBounds::, NoDefault>::DEFAULT, /// NoBounds{bar: None, baz: PhantomData, qux: &[]} /// ); /// ``` /// /// /// ### Replaced Bounds /// /// This example demonstrates replacing the default `ConstDefault` bound on /// type parameters with other bounds. /// /// ```rust /// use core_extensions::ConstDefault; /// /// use std::marker::PhantomData; /// /// #[derive(Debug, PartialEq)] /// struct NoDefault(T); /// /// #[derive(Debug, PartialEq, ConstDefault)] /// // replaces the default `ConstDefault` bound on the `T` type parameter with no bounds. /// #[cdef(bound(T: ))] /// // replaces the default bound on `U` with `Copy + ConstDefault` /// #[cdef(bound(U: Copy + ConstDefault))] /// struct PartialBounds { /// bar: PhantomData, /// baz: U, /// } /// /// const DEF: PartialBounds, u32> = ConstDefault::DEFAULT; /// assert_eq!(DEF, PartialBounds{bar: PhantomData, baz: 0}); /// /// ``` /// /// /// ### Field Bounds /// /// This example demonstrates how the default `ConstDefault` bound on /// type parameters can be replaced with `ConstDefault` bounds on field types. /// /// ```rust /// use core_extensions::ConstDefault; /// /// use std::marker::PhantomData; /// /// #[derive(Debug, PartialEq, ConstDefault)] /// // replaces the default `T: ConstDefault` and `U: ConstDefault` bounds with /// // bounds on the types of the fields: /// // `PhantomData: ConstDefault` and `Custom: ConstDefault` /// #[cdef(field_bound)] /// struct FieldBounds { /// bar: PhantomData, /// baz: Custom, /// } /// /// const DEF: FieldBounds, i32> = FieldBounds::DEFAULT; /// assert_eq!(DEF, FieldBounds{bar: PhantomData, baz: Custom(0)}); /// /// /// #[derive(Debug, PartialEq, ConstDefault)] /// #[cdef(bound(T: ConstDefault + Copy))] /// struct Custom(T); /// /// #[derive(Debug, PartialEq)] /// struct NoDefault(T); /// ``` /// /// /// ### Field Bound /// /// This example demonstrates how the `ConstDefault` bound can be required /// for only some field types. /// /// ```rust /// use core_extensions::ConstDefault; /// /// use std::marker::PhantomData; /// /// #[derive(Debug, PartialEq, ConstDefault)] /// // removes the default `T: ConstDefault` and `U: ConstDefault` bounds /// #[cdef(no_bounds)] /// struct FieldBound { /// bar: PhantomData, /// // Adds a `Custom: ConstDefault` bound /// #[cdef(field_bound)] /// baz: Custom, /// } /// /// const DEF: FieldBound, i32> = FieldBound::DEFAULT; /// assert_eq!(DEF, FieldBound{bar: PhantomData, baz: Custom(0)}); /// /// /// #[derive(Debug, PartialEq, ConstDefault)] /// #[cdef(bound(T: ConstDefault + Copy))] /// struct Custom(T); /// /// #[derive(Debug, PartialEq)] /// struct NoDefault(T); /// ``` /// /// /// ### Extra bounds /// /// This example demonstrates how additional bounds can be put in the /// `ConstDefault` impl. /// /// ```rust /// use core_extensions::ConstDefault; /// /// #[derive(Debug, PartialEq, ConstDefault)] /// // Adds `T: Copy` and `u128: From` bounds to the ConstDefault impl. /// #[cdef(where T: Copy, u128: From)] /// struct ExtraBounds(T); /// /// assert_eq!(ExtraBounds::::DEFAULT, ExtraBounds(0)); /// assert_eq!(ExtraBounds::::DEFAULT, ExtraBounds(0)); /// ``` /// /// [`ConstDefault::DEFAULT`]: ./trait.ConstDefault.html#associatedconstant.DEFAULT /// [`ConstDefault`]: ./trait.ConstDefault.html #[cfg_attr(feature = "docsrs", doc(cfg(all(feature = "derive", feature = "const_default"))))] pub use core_extensions_proc_macros::ConstDefault;