tatara-rust-composite 0.1.3

L2 composition primitive — one `#[derive(Bundle)]` fans out to N inner ProcDerive/PerField/PerVariant Specs. Lifts what users today get from `#[derive(A, B, C)]` into typed data.
Documentation

tatara-rust-composite — L2 composition primitive.

CompositeDeriveSpec bundles N inner derive Specs (any kind) under one user-facing #[derive(<name>)]. The emitted proc-macro crate dispatches the consumer's DeriveInput to each inner Spec's own emitter and concatenates the produced TokenStreams.

Authoring shape:

use tatara_rust_ast::{CompileToCrate, Ident};
use tatara_rust_derive::{PerFieldDeriveSpec, PerFieldTarget};
use tatara_rust_composite::{CompositeDeriveSpec, CompositeMember};

let getter = PerFieldDeriveSpec {
    trait_name: Ident::new("AccessorGetter"),
    target: PerFieldTarget::NamedStruct,
    trait_ref: None,
    per_field_template:
        "pub fn #field_name(&self) -> &#field_ty { &self.#field_name }".into(),
    method_name_template: None,
    impl_prelude: None,
    skip_fields: vec![],
    field_attribute: None,
};
let setter = PerFieldDeriveSpec {
    trait_name: Ident::new("AccessorSetter"),
    target: PerFieldTarget::NamedStruct,
    trait_ref: None,
    per_field_template:
        "pub fn #method_ident(&mut self, v: #field_ty) { self.#field_name = v; }".into(),
    method_name_template: Some("set_{}".into()),
    impl_prelude: None,
    skip_fields: vec![],
    field_attribute: None,
};
let bundle = CompositeDeriveSpec {
    bundle_name: Ident::new("Accessor"),
    members: vec![
        CompositeMember::PerField(getter),
        CompositeMember::PerField(setter),
    ],
};
let scaffold = bundle.compile_to_crate("accessor-derive").unwrap();
assert!(scaffold.to_files().contains_key("src/lib.rs"));