{"id":18062804,"url":"https://github.com/jamjamjon/aksr","last_synced_at":"2026-02-23T14:01:04.914Z","repository":{"id":259677534,"uuid":"879183942","full_name":"jamjamjon/aksr","owner":"jamjamjon","description":"A Rust derive macro that automatically generates Builder Lite pattern methods for structs, supporting both named and tuple structs with extensive customization options.","archived":false,"fork":false,"pushed_at":"2025-11-06T14:36:07.000Z","size":70,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-11-06T16:24:54.283Z","etag":null,"topics":["derive-macro","getters","setters","struct","tuple-struct"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jamjamjon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-10-27T08:20:12.000Z","updated_at":"2025-11-06T14:35:06.000Z","dependencies_parsed_at":"2024-10-27T09:33:51.777Z","dependency_job_id":"68a1b366-d27d-4a57-8ee2-5c6ffa5a8bd5","html_url":"https://github.com/jamjamjon/aksr","commit_stats":null,"previous_names":["jamjamjon/aksr"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/jamjamjon/aksr","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamjamjon%2Faksr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamjamjon%2Faksr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamjamjon%2Faksr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamjamjon%2Faksr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jamjamjon","download_url":"https://codeload.github.com/jamjamjon/aksr/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamjamjon%2Faksr/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29745111,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-23T07:44:07.782Z","status":"ssl_error","status_checked_at":"2026-02-23T07:44:07.432Z","response_time":90,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["derive-macro","getters","setters","struct","tuple-struct"],"created_at":"2024-10-31T05:08:28.971Z","updated_at":"2026-02-23T14:01:04.901Z","avatar_url":"https://github.com/jamjamjon.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# aksr\n\nA Rust derive macro that automatically generates **Builder Lite** pattern methods for structs, supporting both named and tuple structs with extensive customization options.\n\n\n## Builder Lite Pattern\n\n`aksr` implements the [Builder Lite](https://matklad.github.io/2022/05/29/builder-lite.html) 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.\n\n\n**Requirements:**\n- Struct must implement `Default` trait, OR\n- Struct must have a `new()` method\n\nThis allows you to use the builder pattern without creating a separate builder type, making it especially useful for rapidly evolving application code.\n\n\n## Features\n\n- 🚀 **Builder Lite pattern** - Zero-cost, incremental builder evolution\n- 🎯 **Field aliases** for more intuitive API\n- 📦 **Vector extension** methods for incremental updates  \n- 🔧 **Flexible customization** via attributes\n- 💡 **String optimization** with `\u0026str` → `String` and `\u0026[String]` support\n- 🎁 **Smart Option handling** for `Vec\u003cT\u003e` with empty check\n- 🔄 **Ownership methods** - `into_*()` and `take_*()` for efficient value extraction\n- ⚡ **Zero-cost abstractions** following Rust best practices\n\n\n## Installation\n\nAdd `aksr` to your `Cargo.toml`:\n```toml\n[dependencies]\naksr = \"0.0.5\"\n```\n\n\n## Examples\n\nRun the examples to see all features in action:\n\n```bash\ncargo run --example rect        # Named struct\ncargo run --example color       # Tuple struct\n```\n\nTo see the generated code:\n```bash\ncargo install cargo-expand      # Install expand tool\ncargo expand --example rect     # View generated code\n```\n\n- [`examples/rect.rs`](examples/rect.rs) - Named struct with all features\n- [`examples/color.rs`](examples/color.rs) - Tuple struct with all features\n\n\n## Supported Attributes\n\n| Attribute | Description | Values | Example |\n|-----------|-------------|--------|-------------------|\n| `skip` | Skip both getter and setter | `true`, `false` | `#[args(skip = false)]` |\n| `alias` | Field alias for setter/getter | String | `#[args(alias = \"field_name\")]` |\n| `setter` | Control setter generation | `true`, `false` | `#[args(setter = true)]` |\n| `getter` | Control getter generation | `true`, `false` | `#[args(getter = true)]` |\n| `allow` | Whitelist specific features | `setter`, `getter`, `extend`, `skip` | `#[args(allow(xxx, xxx))]` |\n| `except` | Blacklist specific features | `setter`, `getter`, `extend`, `skip`, `into` | `#[args(except(xxx, xxx))]` |\n| `visibility` | Control both getter/setter visibility | `\"pub\"`, `\"private\"`, `\"pub(crate)\"`, `\"pub(self)\"`, `\"pub(super)\"`, `\"pub(in path)\"` | `#[args(visibility = \"pub(crate)\")]` |\n| `setter_visibility` | Control setter visibility (overrides `visibility` if present) | same as above | `#[args(setter_visibility = \"pub\")]` |\n| `getter_visibility` | Control getter visibility (overrides `visibility` if present) | same as above | `#[args(getter_visibility = \"pub\")]` |\n| `setter_prefix` | Custom setter prefix | String | `#[args(setter_prefix = \"with\")]` |\n| `getter_prefix` | Custom getter prefix (named / tuple) | String | `#[args(getter_prefix = \"field_name\")]` / `#[args(getter_prefix = \"nth\")]` |\n| `inline` | Control inline for both getter/setter | `true`, `false`, `\"always\"` | `#[args(inline = true)]` |\n| `getter_inline` | Control getter inline attribute | `true`, `false`, `\"always\"` | `#[args(getter_inline = \"always\")]` |\n| `setter_inline` | Control setter inline attribute | `true`, `false`, `\"always\"` | `#[args(setter_inline = true)]` |\n| `extend` | Enable extend methods for Vec | `true`, `false` | `#[args(extend = false)]` |\n| `into_prefix` | Custom prefix for `into_*()` methods | String (default: `\"into\"`) | `#[args(into_prefix = \"extract\")]` |\n| `except(into)` | Disable `into_*()` method generation | - | `#[args(except(into))]` |\n\n\n## Ownership Methods: `into_*()` and `take_*()`\n\n`aksr` automatically generates ownership methods for fields that own their data, allowing efficient value extraction without cloning.\n\n### `into_*()` Methods\n\n**Generated for:**\n- ✅ Owned types: `Vec\u003cT\u003e`, `String`, `HashMap\u003cK, V\u003e`, `HashSet\u003cT\u003e`, `BTreeMap\u003cK, V\u003e`, `BTreeSet\u003cT\u003e`, etc.\n- ✅ Collections: `VecDeque\u003cT\u003e`, `BinaryHeap\u003cT\u003e`\n- ✅ Smart pointers: `Box\u003cT\u003e`, `Rc\u003cT\u003e`, `Arc\u003cT\u003e`, `Weak\u003cT\u003e`\n- ✅ Wrappers: `RefCell\u003cT\u003e`, `Mutex\u003cT\u003e`, `RwLock\u003cT\u003e`, `Cow\u003c'a, T\u003e`, `OsString`, `PathBuf`\n- ✅ `Option\u003cT\u003e` (any inner type)\n- ✅ Custom owned types (non-primitive)\n- ✅ Arrays and tuples\n- ✅ Reference types (moves the reference itself)\n\n**NOT generated for:**\n- ❌ Primitive/Copy types: `usize`, `bool`, `char`, `i32`, `u8`, `f64`, etc. (getters already return by value)\n- ❌ Fields with `#[args(except(into))]` attribute\n\n**Behavior:**\n- Consumes `self` and moves the field value out\n- Zero-cost: no cloning, just ownership transfer\n- Follows Rust naming convention (like `into_iter()`, `into_inner()`)\n\n**Example:**\n```rust\n#[derive(Builder, Default)]\nstruct Config {\n    items: Vec\u003cString\u003e,\n    name: String,\n    #[args(except(into))]\n    metadata: String,  // No into_metadata() generated\n}\n\nlet config = Config::default()\n    .with_items(\u0026[\"a\", \"b\"])\n    .with_name(\"test\");\n\nlet items = config.into_items();  // Moves Vec\u003cString\u003e out\n// config is now consumed and cannot be used\n```\n\n### `take_*()` Methods\n\n**Generated for:**\n- ✅ `Option\u003cT\u003e` - Uses `Option::take()`, leaves `None` (no `Default` required)\n- ✅ Standard collections (require `Default`):\n  - `Vec\u003cT\u003e`, `String`, `HashMap\u003cK, V\u003e`, `HashSet\u003cT\u003e`\n  - `BTreeMap\u003cK, V\u003e`, `BTreeSet\u003cT\u003e`, `VecDeque\u003cT\u003e`, `BinaryHeap\u003cT\u003e`\n- ✅ Smart pointers: `Box\u003cT\u003e`, `Rc\u003cT\u003e`, `Arc\u003cT\u003e`, `Weak\u003cT\u003e`\n- ✅ Wrappers: `RefCell\u003cT\u003e`, `Mutex\u003cT\u003e`, `RwLock\u003cT\u003e`, `Cow\u003c'a, T\u003e`, `OsString`, `PathBuf`\n\n**NOT generated for:**\n- ❌ Primitive/Copy types\n- ❌ Custom types (unless they implement `Default`)\n- ❌ Types not in the whitelist (to avoid forcing `Default` constraints)\n\n**Behavior:**\n- Takes the field value and replaces it with `Default::default()`\n- Does NOT consume `self` - you can continue using the struct\n- For `Option\u003cT\u003e`, leaves `None` instead of requiring `Default`\n\n**Example:**\n```rust\n#[derive(Builder, Default)]\nstruct Data {\n    items: Vec\u003cString\u003e,\n    opt_value: Option\u003cString\u003e,\n}\n\nlet mut data = Data::default()\n    .with_items(\u0026[\"a\", \"b\"])\n    .with_opt_value(\"test\");\n\nlet items = data.take_items();  // Moves Vec, leaves empty Vec\nassert!(data.items().is_empty());  // Can still use data\n\nlet opt = data.take_opt_value();  // Moves Option, leaves None\nassert_eq!(data.opt_value(), None);  // Can still use data\n```\n\n### Customizing `into_*()` Prefix\n\nIf `into_*()` conflicts with your custom methods, you can change the prefix:\n\n```rust\n#[derive(Builder, Default)]\nstruct Example {\n    #[args(into_prefix = \"extract\")]\n    items: Vec\u003cString\u003e,  // Generates extract_items() instead of into_items()\n}\n```\n\n\n\n## License\nThis project is licensed under [LICENSE](LICENSE).\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjamjamjon%2Faksr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjamjamjon%2Faksr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjamjamjon%2Faksr/lists"}