{"id":20796713,"url":"https://github.com/synphonyte/default-struct-builder","last_synced_at":"2025-07-26T21:34:55.312Z","repository":{"id":170038653,"uuid":"646146470","full_name":"Synphonyte/default-struct-builder","owner":"Synphonyte","description":"Generates builder methods of every field of a struct","archived":false,"fork":false,"pushed_at":"2024-10-01T19:10:25.000Z","size":46,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-05-06T09:18:42.442Z","etag":null,"topics":["builder-pattern","default","macro","rust","struct"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Synphonyte.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","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}},"created_at":"2023-05-27T12:41:05.000Z","updated_at":"2024-10-03T23:48:11.000Z","dependencies_parsed_at":null,"dependency_job_id":"c06b6dc9-63dd-4f6a-b914-50299a7d34d4","html_url":"https://github.com/Synphonyte/default-struct-builder","commit_stats":null,"previous_names":["synphonyte/default-struct-builder"],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Synphonyte%2Fdefault-struct-builder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Synphonyte%2Fdefault-struct-builder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Synphonyte%2Fdefault-struct-builder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Synphonyte%2Fdefault-struct-builder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Synphonyte","download_url":"https://codeload.github.com/Synphonyte/default-struct-builder/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252655007,"owners_count":21783374,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["builder-pattern","default","macro","rust","struct"],"created_at":"2024-11-17T16:28:48.872Z","updated_at":"2025-05-06T09:18:48.263Z","avatar_url":"https://github.com/Synphonyte.png","language":"Rust","readme":"# Default Struct Builder\n\n[![Crates.io](https://img.shields.io/crates/v/default-struct-builder.svg)](https://crates.io/crates/default-struct-builder)\n[![Docs](https://docs.rs/default-struct-builder/badge.svg)](https://docs.rs/default-struct-builder/)\n[![MIT/Apache 2.0](https://img.shields.io/badge/license-MIT%2FApache-blue.svg)](https://github.com/synphonyte/default-struct-builder#license)\n[![Build Status](https://github.com/synphonyte/default-struct-builder/actions/workflows/ci.yml/badge.svg)](https://github.com/synphonyte/default-struct-builder/actions/workflows/ci.yml)\n\n\u003c!-- cargo-rdme start --\u003e\n\nGenerates builder methods of every field of a struct. It is meant to be used on structs that\nimplement `Default`. There is no separate builder struct generated and no need to call a\n`build()` method at the end or `.unwrap()`.\n\nThis crate is used by the crate `leptos-use` for the option structs that\ncan be passed to the various functions.\n\n### Installation\n\nIn your project folder run\n\n```sh\ncargo add default-struct-builder\n```\n\n### Usage\n\nIt is very easy to use:\n\n```rust\nuse default_struct_builder::DefaultBuilder;\n\n#[derive(DefaultBuilder, Default)]\npub struct SomeOptions {\n    throttle: f64,\n\n    #[builder(into)]\n    offset: Option\u003cf64\u003e,\n\n    #[builder(skip)]\n    not_included: u32,\n}\n```\n\nyou can then use the struct like this:\n\n```rust\nlet options = SomeOptions::default().offset(4.0);\n\nassert_eq!(options.offset, Some(4.0));\nassert_eq!(options.throttle, 0.0);\nassert_eq!(options.not_included, 0);\n```\n\n#### Generics\n\nThe macro is ready to be used on generic structs.\n\n```rust\nuse default_struct_builder::DefaultBuilder;\n\n#[derive(DefaultBuilder, Default)]\npub struct SomeOptions\u003cT\u003e\nwhere\n    T: Default,\n{\n    some_field: T,\n}\n```\n\n#### Doc comments\n\nAll doc comments on fields are directly passed on to their generated setter methods.\n\n### How it works\n\nThe derive macro generates the following code:\n\n```rust\nimpl SomeOptions {\n    // setter methods are given that consume `self` and return a new `Self` with the field value changed\n    pub fn throttle(self, value: f64) -\u003e Self {\n        Self {\n            throttle: value,\n            ..self\n        }\n    }\n\n    // because `into` was specified this method is generic and calls `.into()` when setting the value\n    pub fn offset\u003cT\u003e(self, value: T) -\u003e Self\n    where\n        T: Into\u003cOption\u003cf64\u003e\u003e,\n    {\n        Self {\n            offset: value.into(),\n            ..self\n        }\n    }\n\n    // no method for field `not_included` because `skip` was specified\n}\n```\n\n#### Generics\n\nIn the case of a generic field the generated method is a bit more complex because by calling\nthe method the type of the type parameter can be different than before.\n\nLet's look at the following example.\n\n```rust\nuse default_struct_builder::DefaultBuilder;\n\n#[derive(DefaultBuilder, Default)]\npub struct SomeOptions\u003cT\u003e\nwhere\n    T: Default,\n{\n    some_field: T,\n    other_field: i16,\n}\n\nimpl SomeOptions\u003cf32\u003e {\n    pub fn new() -\u003e Self {\n        Self {\n            some_field: 42.0,\n            other_field: 0,\n        }   \n    }\n}\n```\n\nThis generates the setter method below.\n\n```rust\nimpl\u003cT\u003e SomeOptions\u003cT\u003e\nwhere\n    T: Default,\n{\n    pub fn some_field\u003cNewT\u003e(self, value: NewT) -\u003e SomeOptions\u003cNewT\u003e\n    where\n        NewT: Default,\n    {\n        SomeOptions::\u003cNewT\u003e {\n            some_field: value,\n            other_field: self.other_field,\n        }\n    }\n}\n\nfn main() {\n   let options = SomeOptions::new()  // at first    SomeOptions\u003cf32\u003e\n        .some_field(\"string\");       // changed to  SomeOptions\u003c\u0026str\u003e\n}\n```\n\nIn cases where you don't want a generic field to be able to change the generic type you\ncan annotate it with `keep_type`.\n\n```rust\n#[derive(DefaultBuilder)]\nstruct SomeOptions\u003cT\u003e {\n    #[builder(keep_type)]\n    the_field: T,\n}\n```\n\nthis will generate a standard builder method as if `T` wasn't generic.\n\n#### `Box`, `Rc` and `Arc`\n\nThe macro detects if a field is a `Box` (or `Rc` or `Arc`) and generates a builder method that\naccepts the inner type (without `Box` or `Rc` or `Arc`) and adds the outer type in the body.\n\nIn case it's a `Box\u003cdyn Trait\u003e` the builder method will have an argument of type\n`impl Trait`. The same goes for `Rc` and `Arc`.\n\nIf you want to prevent this auto un-wrapping you can use the `#[builder(keep_outer)]` attribute.\n\n```rust\ntrait Test {}\n\n#[derive(DefaultBuilder)]\nstruct SomeOptions {\n    the_field: Box\u003cdyn Test\u003e,\n    other_field: Rc\u003cString\u003e,\n\n    #[builder(keep_outer)]\n    keep: Box\u003cString\u003e,\n}\n```\n\nThis will generate the following code:\n\n```rust\nimpl SomeOptions {\n    pub fn the_field(self, value: impl Test + 'static) -\u003e Self {\n        Self {\n            the_field: Box::new(value),\n            ..self\n        }   \n    }\n\n    pub fn other_field(self, value: String) -\u003e Self {\n        Self {\n            other_field: Rc::new(value),\n            ..self\n        }\n    }\n\n    pub fn keep(self, value: Box\u003cString\u003e) -\u003e Self {\n        Self {\n            keep: value,\n            ..self\n        }   \n    }\n}\n```\n\n\n### Related Work\n\nFor more general purposes please check out the much more powerful\n[`derive_builder` crate](https://github.com/colin-kiegel/rust-derive-builder).\n\n\u003c!-- cargo-rdme end --\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsynphonyte%2Fdefault-struct-builder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsynphonyte%2Fdefault-struct-builder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsynphonyte%2Fdefault-struct-builder/lists"}