| Crates.io | aksr |
| lib.rs | aksr |
| version | 0.0.7 |
| created_at | 2024-10-29 12:26:18.734147+00 |
| updated_at | 2025-11-06 14:43:26.737228+00 |
| description | A Rust derive macro designed to automatically generate getter and setter methods for both named and tuple structs. |
| homepage | |
| repository | https://github.com/jamjamjon/aksr |
| max_upload_size | |
| id | 1426967 |
| size | 152,054 |
A Rust derive macro that automatically generates Builder Lite pattern methods for structs, supporting both named and tuple structs with extensive customization options.
aksr implements the Builder Lite pattern, where the struct itself acts as the builder. Unlike traditional builders that require a separate builder object, Builder Lite is an incremental, zero-cost evolution from the new() or Default::default() method.
Requirements:
Default trait, ORnew() methodThis allows you to use the builder pattern without creating a separate builder type, making it especially useful for rapidly evolving application code.
🚀 Builder Lite pattern - Zero-cost, incremental builder evolution
🎯 Field aliases for more intuitive API
📦 Vector extension methods for incremental updates
🔧 Flexible customization via attributes
💡 String optimization with &str → String and &[String] support
🎁 Smart Option handling for Vec<T> with empty check
🔄 Ownership methods - into_*() and take_*() for efficient value extraction
⚡ Zero-cost abstractions following Rust best practices
Add aksr to your Cargo.toml:
[dependencies]
aksr = "0.0.5"
Run the examples to see all features in action:
cargo run --example rect # Named struct
cargo run --example color # Tuple struct
To see the generated code:
cargo install cargo-expand # Install expand tool
cargo expand --example rect # View generated code
examples/rect.rs - Named struct with all features
examples/color.rs - Tuple struct with all features
| Attribute | Description | Values | Example |
|---|---|---|---|
skip |
Skip both getter and setter | true, false |
#[args(skip = false)] |
alias |
Field alias for setter/getter | String | #[args(alias = "field_name")] |
setter |
Control setter generation | true, false |
#[args(setter = true)] |
getter |
Control getter generation | true, false |
#[args(getter = true)] |
allow |
Whitelist specific features | setter, getter, extend, skip |
#[args(allow(xxx, xxx))] |
except |
Blacklist specific features | setter, getter, extend, skip, into |
#[args(except(xxx, xxx))] |
visibility |
Control both getter/setter visibility | "pub", "private", "pub(crate)", "pub(self)", "pub(super)", "pub(in path)" |
#[args(visibility = "pub(crate)")] |
setter_visibility |
Control setter visibility (overrides visibility if present) |
same as above | #[args(setter_visibility = "pub")] |
getter_visibility |
Control getter visibility (overrides visibility if present) |
same as above | #[args(getter_visibility = "pub")] |
setter_prefix |
Custom setter prefix | String | #[args(setter_prefix = "with")] |
getter_prefix |
Custom getter prefix (named / tuple) | String | #[args(getter_prefix = "field_name")] / #[args(getter_prefix = "nth")] |
inline |
Control inline for both getter/setter | true, false, "always" |
#[args(inline = true)] |
getter_inline |
Control getter inline attribute | true, false, "always" |
#[args(getter_inline = "always")] |
setter_inline |
Control setter inline attribute | true, false, "always" |
#[args(setter_inline = true)] |
extend |
Enable extend methods for Vec | true, false |
#[args(extend = false)] |
into_prefix |
Custom prefix for into_*() methods |
String (default: "into") |
#[args(into_prefix = "extract")] |
except(into) |
Disable into_*() method generation |
- | #[args(except(into))] |
into_*() and take_*()aksr automatically generates ownership methods for fields that own their data, allowing efficient value extraction without cloning.
into_*() MethodsGenerated for:
Vec<T>, String, HashMap<K, V>, HashSet<T>, BTreeMap<K, V>, BTreeSet<T>, etc.VecDeque<T>, BinaryHeap<T>Box<T>, Rc<T>, Arc<T>, Weak<T>RefCell<T>, Mutex<T>, RwLock<T>, Cow<'a, T>, OsString, PathBufOption<T> (any inner type)NOT generated for:
usize, bool, char, i32, u8, f64, etc. (getters already return by value)#[args(except(into))] attributeBehavior:
self and moves the field value outinto_iter(), into_inner())Example:
#[derive(Builder, Default)]
struct Config {
items: Vec<String>,
name: String,
#[args(except(into))]
metadata: String, // No into_metadata() generated
}
let config = Config::default()
.with_items(&["a", "b"])
.with_name("test");
let items = config.into_items(); // Moves Vec<String> out
// config is now consumed and cannot be used
take_*() MethodsGenerated for:
Option<T> - Uses Option::take(), leaves None (no Default required)Default):
Vec<T>, String, HashMap<K, V>, HashSet<T>BTreeMap<K, V>, BTreeSet<T>, VecDeque<T>, BinaryHeap<T>Box<T>, Rc<T>, Arc<T>, Weak<T>RefCell<T>, Mutex<T>, RwLock<T>, Cow<'a, T>, OsString, PathBufNOT generated for:
Default)Default constraints)Behavior:
Default::default()self - you can continue using the structOption<T>, leaves None instead of requiring DefaultExample:
#[derive(Builder, Default)]
struct Data {
items: Vec<String>,
opt_value: Option<String>,
}
let mut data = Data::default()
.with_items(&["a", "b"])
.with_opt_value("test");
let items = data.take_items(); // Moves Vec, leaves empty Vec
assert!(data.items().is_empty()); // Can still use data
let opt = data.take_opt_value(); // Moves Option, leaves None
assert_eq!(data.opt_value(), None); // Can still use data
into_*() PrefixIf into_*() conflicts with your custom methods, you can change the prefix:
#[derive(Builder, Default)]
struct Example {
#[args(into_prefix = "extract")]
items: Vec<String>, // Generates extract_items() instead of into_items()
}
This project is licensed under LICENSE.