{"id":16783337,"url":"https://github.com/bengreenier/partially","last_synced_at":"2026-02-21T21:02:43.005Z","repository":{"id":195396070,"uuid":"692838398","full_name":"bengreenier/partially","owner":"bengreenier","description":"Rust crate that provides the Partial trait, and an optional macro to mirror a struct, wrapping each field in an Option.","archived":false,"fork":false,"pushed_at":"2024-01-20T22:49:26.000Z","size":46,"stargazers_count":6,"open_issues_count":4,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-24T19:21:39.912Z","etag":null,"topics":["rust","rust-patterns"],"latest_commit_sha":null,"homepage":"https://crates.io/crates/partially","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/bengreenier.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-09-17T18:28:01.000Z","updated_at":"2024-12-31T19:14:22.000Z","dependencies_parsed_at":null,"dependency_job_id":"5ccd52ca-8c61-4793-b2cf-e36dcd650c43","html_url":"https://github.com/bengreenier/partially","commit_stats":null,"previous_names":["bengreenier/partially"],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bengreenier%2Fpartially","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bengreenier%2Fpartially/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bengreenier%2Fpartially/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bengreenier%2Fpartially/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bengreenier","download_url":"https://codeload.github.com/bengreenier/partially/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248306280,"owners_count":21081654,"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":["rust","rust-patterns"],"created_at":"2024-10-13T07:49:29.740Z","updated_at":"2026-02-21T21:02:37.976Z","avatar_url":"https://github.com/bengreenier.png","language":"Rust","readme":"# partially\r\n\r\n\u003e Provides a configurable [derive macro](https://doc.rust-lang.org/reference/procedural-macros.html#derive-macros) that generates another struct with the same fields, but wrapped in `Option\u003cT\u003e`, and implements `Partial` to allow conditionally applying the generated struct fields to the base struct fields.\r\n\r\n`partially` provides the `Partial` trait, which allows applying another structs values to `self`, with the intent that the other struct mirrors the fields of `self`, but wrapped in `Option\u003cT\u003e`.\r\n\r\nFurther, `partially_derive` (or `partially` with the `derive` feature enabled) supports automatically generating a mirrored struct with each field wrapped in `Option\u003cT\u003e`, **and** generates a `Partial` implementation that allows applying the `Some` fields of the mirrored struct to the base struct. I expect most folks will be most interested in using the derive macro.\r\n\r\n## Usage\r\n\r\nWith derive:\r\n\r\n```rust\r\n// `partially` installed with feature `derive`\r\nuse partially::Partial;\r\n\r\n// define a base structure, with the `Partial` derive macro\r\n#[derive(Partial)]\r\n// further, instruct the macro to derive `Default` on the generated structure\r\n#[partially(derive(Default))]\r\nstruct Data {\r\n    // since no field options are specified, this field will be mapped\r\n    // to an `Option\u003cString\u003e` in the generated structure\r\n    value: String,\r\n}\r\n\r\n// example usage\r\nfn main() {\r\n    // since we derived default for the generated struct, we can use that\r\n    // to obtain a partial struct filled with `None`.\r\n    let empty_partial = PartialData::default();\r\n\r\n    // we can, of course, also specify values ourself\r\n    let full_partial = PartialData {\r\n        value: Some(\"modified\".to_string()),\r\n    };\r\n\r\n    // define a \"base\" that we'll operate against\r\n    let mut full = Data {\r\n        value: \"initial\".to_string(),\r\n    };\r\n\r\n    // apply the empty partial (note that `false` is returned, indicating nothing was applied)\r\n    assert!(!full.apply_some(empty_partial));\r\n\r\n    // note that applying the empty partial had no effect\r\n    assert_eq!(full.value, \"initial\".to_string());\r\n\r\n    // apply the full partial (note that `true` is returned, indicating something was applied)\r\n    assert!(full.apply_some(full_partial));\r\n\r\n    // note that applying the full partial modified the value\r\n    assert_eq!(full.value, \"modified\".to_string());\r\n}\r\n```\r\n\r\nWithout derive:\r\n\r\n```rust\r\nuse partially::Partial;\r\n\r\nstruct Base {\r\n    value: String,\r\n}\r\n\r\n#[derive(Default)]\r\nstruct PartialBase {\r\n    value: Option\u003cString\u003e,\r\n}\r\n\r\nimpl Partial for Base {\r\n    type Item = PartialBase;\r\n\r\n    #[allow(clippy::useless_conversion)]\r\n    fn apply_some(\u0026mut self, partial: Self::Item) -\u003e bool {\r\n        let will_apply_some = partial.value.is_some();\r\n\r\n        if let Some(value) = partial.value {\r\n            self.value = value.into();\r\n        }\r\n\r\n        will_apply_some\r\n    }\r\n}\r\n\r\nfn main() {\r\n    let empty_partial = PartialBase::default();\r\n    let full_partial = PartialBase {\r\n        value: Some(\"modified\".to_string()),\r\n    };\r\n\r\n    let mut data = Base {\r\n        value: \"initial\".to_string(),\r\n    };\r\n\r\n    assert!(!data.apply_some(empty_partial));\r\n\r\n    assert_eq!(data.value, \"initial\".to_string());\r\n\r\n    assert!(data.apply_some(full_partial));\r\n\r\n    assert_eq!(data.value, \"modified\".to_string())\r\n}\r\n\r\n```\r\n\r\n### Struct Options\r\n\r\n#### derive\r\n\r\n\u003e Usage example: `#[partially(derive(Debug, Default))]`.\r\n\r\nInstructs the macro to generate a `#[derive(...)]` attribute on the generated struct.\r\n\r\nNote: When using this option with the `skip_attributes` option, the derive attribute **will still be added to the generated struct**.\r\n\r\n#### rename\r\n\r\n\u003e Usage example: `#[partially(rename = \"MyGeneratedStruct\")]`.\r\n\r\nInstructs the macro to use a given identifier for the generated struct. By default, `PartialBaseStructName` is used, where `BaseStructName` is the name of the original struct.\r\n\r\n#### attribute\r\n\r\n\u003e Usage example: `#[partially(attribute(serde(rename_all = \"PascalCase\")))]`\r\n\r\nInstructs the macro to add an additional attribute to the generated struct. By default, the attributes defined on the base struct are forwarded to the generated struct, unless the `skip_attributes` option is present.\r\n\r\n#### skip_attributes\r\n\r\n\u003e Usage example: `#[partially(skip_attributes)]`.\r\n\r\nInstructs the macro to skip forwarding attributes from the original struct to the generated struct. By default, all attributes that are present on the base struct are added to the generated struct.\r\n\r\nNote: When using this option with the `derive` option, the derive attribute **will still be added to the generated struct**.\r\n\r\nNote: When using this option with the `attribute` option, the specified attribute(s) **will still be added to the generated struct**.\r\n\r\n#### crate\r\n\r\n\u003e Usage example: `#[partially(crate = \"my_partially_crate\")]`.\r\n\r\nInstructs the macro to use a different base path for the `Partial` trait implementation. By default, `partially` is used. This can be useful if you've forked the `partially` crate.\r\n\r\n### Field Options\r\n\r\n#### rename\r\n\r\n\u003e Usage example: `#[partially(rename = \"new_field_name\")]`.\r\n\r\nInstructs the macro to use a given identifier for the generated field. By default, the same name as the base struct is used.\r\n\r\n#### omit\r\n\r\n\u003e Usage example: `#[partially(omit)]`.\r\n\r\nInstructs the macro to omit the field from the generated struct. By default, no fields are omitted.\r\n\r\n#### transparent\r\n\r\n\u003e Usage example: `#[partially(transparent)]`.\r\n\r\nInstructs the macro to skip wrapping the generated field in `Option\u003cT\u003e`, instead transparently mirroring the field type into the generated struct.\r\n\r\n#### as_type\r\n\r\n\u003e Usage example: `#[partially(as_type = \"Option\u003cf32\u003e\")]`.\r\n\r\nInstructs the macro to use the provided type instead of `Option\u003cT\u003e` when generating the field. Note that the provided type will be used verbatim, so if you expect an `Option\u003cT\u003e` value, you'll need to manually specify that.\r\n\r\nNote: When using `as_type`, the given type must `Into\u003cBaseType\u003e` where `BaseType` is the original field type. This is required for `Partial` trait implementation.\r\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbengreenier%2Fpartially","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbengreenier%2Fpartially","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbengreenier%2Fpartially/lists"}