build-deftly 0.1.0

Derive custom builders, using the derive-deftly macro system
Documentation
use assert_matches::assert_matches;
use build_deftly::prelude::*;
use derive_deftly::Deftly;

#[test]
fn nil() {
    #[derive(Deftly, Debug)]
    #[derive_deftly(Builder)]
    struct Nil {}

    let nil = Nil::builder().build().unwrap();
    assert!(matches!(nil, Nil {}));
}

#[test]
fn small() {
    #[derive(Deftly, Debug)]
    #[derive_deftly(Builder)]
    struct Small {
        /// Hello
        hello: String,
        /// World
        world: u32,
    }

    let small = Small::builder()
        .hello("Hello".into())
        .world(42)
        .build()
        .unwrap();
    assert_eq!(&small.hello, "Hello");
    assert_eq!(small.world, 42);

    assert_matches!(
        Small::builder().build(),
        Err(SmallBuilderError::UninitializedField(_))
    );
    assert_matches!(
        Small::builder().hello("Hello".into()).build(),
        Err(SmallBuilderError::UninitializedField(_))
    );
    assert_matches!(
        Small::builder().world(42).build(),
        Err(SmallBuilderError::UninitializedField(_))
    );
}

#[test]
fn pattern_owned() {
    // This doesn't implement clone, so we'll have to use the "owned" pattern.
    #[derive(Debug)]
    struct NotClone {}

    #[derive(Deftly, Debug)]
    #[derive_deftly(Builder)]
    #[deftly(builder(pattern = "owned"))]
    struct Small {
        hello: String,
        world: u32,
        _uncloneable: NotClone,
    }

    let small = Small::builder()
        .hello("Hello".into())
        .world(42)
        ._uncloneable(NotClone {})
        .build()
        .unwrap();
    assert_eq!(&small.hello, "Hello");
    assert_eq!(small.world, 42);
}

#[test]
fn pattern_immut() {
    #[derive(Deftly, Debug)]
    #[derive_deftly(Builder)]
    #[deftly(builder(pattern = "immutable"))]
    struct Small {
        hello: String,
        world: u32,
    }

    let small = Small::builder()
        .hello("Hello".into())
        .world(42)
        .build()
        .unwrap();
    assert_eq!(&small.hello, "Hello");
    assert_eq!(small.world, 42);
}

#[test]
fn skip_setters_outer() {
    #[derive(Deftly, Debug)]
    #[derive_deftly(Builder)]
    #[deftly(builder(setter(skip)))]
    struct Small {
        hello: String,
        world: u32,
    }

    let small = Small::builder().build().unwrap();
    assert_eq!(&small.hello, "");
    assert_eq!(small.world, 0);
}

#[test]
fn skip_setters_inner() {
    #[derive(Deftly, Debug)]
    #[derive_deftly(Builder)]
    struct Small {
        hello: String,
        #[deftly(builder(setter(skip)))]
        world: u32,
    }

    let small = Small::builder().hello("hi".to_string()).build().unwrap();
    assert_eq!(&small.hello, "hi");
    assert_eq!(small.world, 0);
}

#[test]
fn skip_setters_dflt() {
    #[derive(Deftly, Debug)]
    #[derive_deftly(Builder)]
    #[deftly(builder(setter(skip)))]
    struct Small {
        #[deftly(builder(setter(enabled)))]
        hello: String,
        world: u32,
    }

    let small = Small::builder().hello("hi".to_string()).build().unwrap();
    assert_eq!(&small.hello, "hi");
    assert_eq!(small.world, 0);
}