{"id":16118516,"url":"https://github.com/duskmoon314/utility-rs","last_synced_at":"2025-04-26T12:29:51.779Z","repository":{"id":43307128,"uuid":"431779232","full_name":"duskmoon314/utility-rs","owner":"duskmoon314","description":"Try impl TypeScript's utility types in rust via proc_macro","archived":false,"fork":false,"pushed_at":"2024-07-30T10:28:27.000Z","size":33,"stargazers_count":25,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-14T14:09:52.693Z","etag":null,"topics":["proc-macro","rust"],"latest_commit_sha":null,"homepage":"https://crates.io/crates/utility-types","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/duskmoon314.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}},"created_at":"2021-11-25T09:06:00.000Z","updated_at":"2025-01-20T19:41:26.000Z","dependencies_parsed_at":"2024-06-16T04:57:23.328Z","dependency_job_id":"e0470bcf-4423-4125-bcd2-f1e3f11a9d62","html_url":"https://github.com/duskmoon314/utility-rs","commit_stats":{"total_commits":5,"total_committers":2,"mean_commits":2.5,"dds":"0.19999999999999996","last_synced_commit":"3f63cbd4216be40e6d28596397319f88671e0964"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duskmoon314%2Futility-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duskmoon314%2Futility-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duskmoon314%2Futility-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duskmoon314%2Futility-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/duskmoon314","download_url":"https://codeload.github.com/duskmoon314/utility-rs/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250803923,"owners_count":21490171,"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":["proc-macro","rust"],"created_at":"2024-10-09T20:49:46.304Z","updated_at":"2025-04-25T10:49:34.696Z","avatar_url":"https://github.com/duskmoon314.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# utility types\n\nThis crate use proc-macro to realize several utility types of Typescript in Rust.\n\n| macro     | Typescript Utility Type                                                                                                                   |\n| --------- | ----------------------------------------------------------------------------------------------------------------------------------------- |\n| [Partial] | [Partial\\\u003cType\\\u003e](https://www.typescriptlang.org/docs/handbook/utility-types.html#partialtype)                                            |\n| [Pick]    | [Pick\\\u003cType, Keys\\\u003e](https://www.typescriptlang.org/docs/handbook/utility-types.html#picktype-keys)                                       |\n| [Omit]    | [Omit\\\u003cType, Keys\\\u003e](https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys)                                       |\n| [Extract] | [Extract\\\u003cType, Union\\\u003e](https://www.typescriptlang.org/docs/handbook/utility-types.html#extracttype-union)                               |\n| [Exclude] | [Exclude\\\u003cUnionType, ExcludedMembers\\\u003e](https://www.typescriptlang.org/docs/handbook/utility-types.html#excludeuniontype-excludedmembers) |\n\n## Example\n\nHere is an example of how to use this crate.\n\n```rust\nuse utility_types::{Omit, Partial, Pick, Required};\n#[derive(Clone, Partial, Required, Pick, Omit)]\n#[partial(ident = PartialFoo, derive(Debug, PartialEq), forward_attrs())]\n#[required(ident = RequiredFoo, derive(Debug, PartialEq), forward_attrs())]\n#[pick(arg(ident = PickAB, fields(a, b), derive(Debug, PartialEq)), forward_attrs())]\n#[omit(arg(ident = OmitCD, fields(c, d), derive(Debug, PartialEq)), forward_attrs())]\npub struct Foo {\n    a: u8,\n    b: Option\u003cu8\u003e,\n    c: Option\u003cVec\u003cu8\u003e\u003e,\n}\n```\n\nThe above code will generate the following code.\n\n```rust\n#[derive(Debug, PartialEq)]\npub struct PartialFoo {\n    a: Option\u003cu8\u003e,\n    b: Option\u003cOption\u003cu8\u003e\u003e,\n    c: Option\u003cOption\u003cVec\u003cu8\u003e\u003e\u003e,\n}\n#[derive(Debug, PartialEq)]\npub struct RequiredFoo {\n    a: u8,\n    b: u8,\n    c: Vec\u003cu8\u003e,\n}\n#[derive(Debug, PartialEq)]\npub struct PickAB {\n    a: u8,\n    b: Option\u003cu8\u003e,\n}\n#[derive(Debug, PartialEq)]\npub struct OmitCD {\n    a: u8,\n    b: Option\u003cu8\u003e,\n}\n```\n\nSome useful traits are also generated:\n\n- `From\u003cFoo\u003e` for `PartialFoo`, `PickAB`, `OmitCD`\n- `From\u003cPartialFoo\u003e` for `Foo`\n\n### Forwarding Attributes\n\nTo use this crate with other crates that need attributes, you can use the `forward_attrs` attribute to control which attributes are forwarded to the generated struct or enum.\n\n```rust\nuse serde::{Deserialize, Serialize};\nuse utility_types::Omit;\n\n#[derive(Debug, PartialEq, Serialize, Deserialize, Omit)]\n#[omit(\n    arg(\n        ident = OmitCD,\n        fields(c, d),\n        derive(Debug, PartialEq, Serialize, Deserialize),\n        forward_attrs(serde)\n    )\n)]\n#[serde(rename_all = \"UPPERCASE\")]\npub struct Foo {\n    a: u8,\n    b: Option\u003cu8\u003e,\n    c: Option\u003cVec\u003cu8\u003e\u003e,\n}\n\nlet omit_cd: OmitCD = serde_json::from_str(r#\"{\"A\": 1, \"B\": 2}\"#).unwrap();\nassert_eq!(omit_cd, OmitCD { a: 1, b: Some(2) });\n```\n\nThe behavior of the `forward_attrs` attribute is as follows:\n\n- If **not provided**, all attributes are forwarded by default.\n- If provided with a list of attributes, only the specified attributes are forwarded.\n  - For example, `forward_attrs(doc, serde)` will forward only `doc` and `serde`.\n  - If provided with **only `*`** (`forward_attrs(*)`), all attributes are forwarded.\n  - If provided with **an empty list** (`forward_attrs()`), no attributes are forwarded.\n- If provided with a list inside `not()`, all attributes except the specified attributes are forwarded.\n  - For example, `forward_attrs(not(serde))` will forward all attributes except `serde`.\n\n## Known Issue\n\nCurrently I don't analyze which generic is used in the generated struct or enum. So rustc will complain if the field with generic is not included in the generated struct or enum.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fduskmoon314%2Futility-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fduskmoon314%2Futility-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fduskmoon314%2Futility-rs/lists"}