Skip to main content

derive_deftly_template_Constructor

Macro derive_deftly_template_Constructor 

Source
macro_rules! derive_deftly_template_Constructor {
    ({ $($driver:tt)* } [$($aoptions:tt)*] ($($future:tt)*) $($tpassthrough:tt)*) => { ... };
    ($($wrong:tt)*) => { ... };
}
Expand description

Defines a constructor struct and method

“Constructor” is a more lightweight alternative to the builder pattern.

§Comparison to builders

  • Suitable for transparent, rather than opaque, structs.
  • Missing fields during construction are detected at compile-time.
  • Construction is infallible at runtime.
  • Making a previously-required field optional is an API break.

§Input

  • struct Thing. (enums and unions are not supported.)

  • Each field must impl Default or be annotated #[deftly(constructor)]

  • Thing should contain #[doc(hidden)] pub __non_exhaustive: () rather than being #[non_exhaustive]. (Because struct literal syntax is not available otherwise.)

§Generated items

  • pub struct ThingConstructor: contains all the required (non-optional) fields from Thing. ThingConstructor is exhaustive.

  • fn ThingConstructor::construct(self) -> Thing: fills in all the default values.

  • impl From<ThingConstructor> for Thing

§Attributes

§Field attributes

  • #[deftly(constructor)]: Include this field in ThingConstructor. The caller must provide a value.

  • #[deftly(constructor(default = EXPR))]: Instead of Default::default(), the default value is EXPR. EXPR cannot refer to anything in ThingConstructor.

§Example

use derive_deftly::Deftly;
use tor_netdoc::derive_deftly_template_Constructor;

#[derive(Deftly, PartialEq, Debug)]
#[derive_deftly(Constructor)]
#[allow(clippy::exhaustive_structs)]
pub struct Thing {
    /// Required field
    #[deftly(constructor)]
    pub required: i32,

    /// Optional field
    pub optional: Option<i32>,

    /// Optional field with fixed default
    #[deftly(constructor(default = 7))]
    pub defaulted: i32,

    #[doc(hidden)]
    pub __non_exhaustive: (),
}

let thing = Thing {
    optional: Some(23),
    ..ThingConstructor {
        required: 12,
    }.construct()
};

assert_eq!(
    thing,
    Thing {
        required: 12,
        optional: Some(23),
        defaulted: 7,
        __non_exhaustive: (),
    }
);

§Note

This is a derive_deftly template. Do not invoke it directly. To use it, write: #[derive(Deftly)] #[derive_deftly(Constructor)].