facet-default

facet-default derives Default for your types through facet's plugin system, letting you supply per-field defaults directly in the struct definition rather than writing a manual impl.

rust
use facet::Facet;
use facet_default as default;

#[derive(Facet, Debug)]
#[facet(derive(Default))]
pub struct Config {
    #[facet(default::value = "localhost")]
    host: String,
    #[facet(default::value = 8080u16)]
    port: u16,
    #[facet(default::func = "default_timeout")]
    timeout: std::time::Duration,
    // No attribute = uses Default::default()
    debug: bool,
}

fn default_timeout() -> std::time::Duration {
    std::time::Duration::from_secs(30)
}

Attributes

Field level

  • #[facet(default::value = literal)] — use a literal value (converted via .into())
  • #[facet(default::func = "path")] — call a function to get the default value

Fields without attributes fall back to Default::default(). For numeric literals, include a type suffix (e.g. 8080u16) to avoid ambiguity. String literals are automatically converted via .into().

Enums

For enums, mark the default variant with #[facet(default::variant)]:

rust
use facet::Facet;
use facet_default as default;

#[derive(Facet, Debug, PartialEq)]
#[facet(derive(Default))]
#[repr(u8)]
pub enum Status {
    #[facet(default::variant)]
    Pending,
    Active,
    Done,
}

assert_eq!(Status::default(), Status::Pending);

Enum variants with fields work the same way — each field uses its own default attributes.

Sponsors

Thanks to all individual sponsors:

GitHub Sponsors Patreon

...along with corporate sponsors:

AWS Zed Depot

...without whom this work could not exist.

Special thanks

The facet logo was drawn by Misiasart.

License

Licensed under either of:

at your option.