{"id":22747439,"url":"https://github.com/dekirisu/type_cell","last_synced_at":"2025-04-14T11:40:38.717Z","repository":{"id":193824054,"uuid":"684992213","full_name":"dekirisu/type_cell","owner":"dekirisu","description":"Attach values statically to a type using static get/set methods.","archived":false,"fork":false,"pushed_at":"2023-12-29T04:10:07.000Z","size":40,"stargazers_count":17,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-28T00:45:05.852Z","etag":null,"topics":["lazy","macro","static"],"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/dekirisu.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}},"created_at":"2023-08-30T09:26:59.000Z","updated_at":"2024-11-09T10:34:13.000Z","dependencies_parsed_at":"2023-09-10T09:07:03.636Z","dependency_job_id":"ac98e67d-0e99-45cc-b996-d60ba0e514c1","html_url":"https://github.com/dekirisu/type_cell","commit_stats":null,"previous_names":["dekirisu/type_cell"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dekirisu%2Ftype_cell","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dekirisu%2Ftype_cell/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dekirisu%2Ftype_cell/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dekirisu%2Ftype_cell/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dekirisu","download_url":"https://codeload.github.com/dekirisu/type_cell/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248874212,"owners_count":21175791,"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":["lazy","macro","static"],"created_at":"2024-12-11T03:15:40.250Z","updated_at":"2025-04-14T11:40:38.690Z","avatar_url":"https://github.com/dekirisu.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://user-images.githubusercontent.com/78398528/282165324-e99cae4c-ce93-402c-949f-3f48708a716b.gif\"\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/dekirisu/type_cell\" style=\"position:relative\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/github-dekirisu/type_cell-ee6677\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://crates.io/crates/type_cell\" style=\"position:relative\"\u003e\n        \u003cimg src=\"https://img.shields.io/crates/v/type_cell\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://docs.rs/type_cell\" style=\"position:relative\"\u003e\n        \u003cimg src=\"https://img.shields.io/docsrs/type_cell\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\nMacro to 'attach' values statically to a type using static getter and setter methods.\n```toml\n[dependencies]\ntype_cell = \"0.3\"\n```\n```rust\nuse type_cell::*;\n\ntycell!{\n    {String} \n        [nice_str]\n        [lazy_str.clone() -\u003e String {\"hello\"}]\n    {bool \u003e Vec\u003cbool\u003e} \n        [is_nice]\n    {!Vec\u003cbool\u003e} \n        [are_nice]\n}\n\nfn main(){\n    String::set_nice_str(\"world\");\n    assert_eq!(\n        \"hello world\",\n        \u0026format!(\"{} {}\",\u0026String::lazy_str(),String::nice_str())\n    );\n}\n```\n## 🧱 Basic Usage\n- Use the macro: `tycell!{...}`\n- Which type should the value be 'attached' on? `u32 {...}`\n- Which type does the value have? `static u32:`\n    - Which settings will it use?\u003cbr\u003e\n    🌟 `once_read` Set it once. Get it read-only! (combine with Mutex/RwLock/... for mutability)\u003cbr\u003e\n    🏁 `once_write` Set it once. Get it mutable, but risk race conditions! (be sure you win the race!)\u003cbr\u003e\n    🦥 `lazy_read` Like `once_read` but set lazy inside the macro!\u003cbr\u003e\n    👹 `lazy_write`Like `once_write` but set lazy inside the macro!! \n    - examples: `static u32: once_read;` or `static String: lazy_read;`\n- What's the name of the default setter method? `set_type()`\n- What's the name of the default getter method? `get_type()`\n\n```rust\n// Basic Usage \ntycell!{ bool {\n    static Vec\u003cbool\u003e: once_read;\n    set set_vec();\n    get vec();\n}}\n// Set it somewhere once:\nbool::set_vec(Vec::from([true,false,true]));\n// Get it anywhere afterwards:\nassert_eq!(\u0026[true,false,true],bool::vec().as_slice());\n```\nThe default setter parameter is a dynamic `Into\u003c..\u003e` and will use `.into()`.\u003cbr\u003e\nThis means in this example you could also set it like this:\n```rust\nbool::set_vec([true,false,true]);\nassert_eq!(\u0026[true,false,true],bool::vec().as_slice());\n```\n## ⚗ Advanced Usage\nMultiple Setter and Getter with different parameters and return types can be defined! \u003cbr\u003e\nThere are two ways of doing it:\n- **Methods:** \n    - Use inline methods for simple conversions!\n    - `set set_bool(Option\u003cusize\u003e): do.is_some();`\n    - `get get_bool() -\u003e bool: static.clone();`\n- **Function:** \n    - Use a function with correct parameters/return types and is accessible in the same file!\n    - Use `=` before the function meta!\n    - `set =set_base_fn(a:Option\u003cusize\u003e);` \n    - `get =get_base_fn() -\u003e bool;`\n```rust\n// Advanced Usage \nfn set_by_function (a:Option\u003cusize\u003e) -\u003e bool {a.is_some()}\nfn get_by_function (a:\u0026bool) -\u003e bool {a.clone()}\ntycell!{ bool {\n    static bool: once_read;\n    set set_raw();\n    set set_by_methods(Option\u003cusize\u003e): do.is_some();\n    set =set_by_function(a:Option\u003cusize\u003e);\n    get get_raw();\n    get get_by_methods() -\u003e bool: static.clone();\n    get =get_by_function() -\u003e bool;\n}}\nbool::set_by_methods(None);\nassert_eq!(false,bool::get_by_methods());\n```\nMethods with parameters are supported in two different ways:\n- **Constants:**\n    - Using `=` before a constant value!\n    - `set set_number(u32): do.clamp(=0,=100);`\n    - `get get_number() -\u003e bool: static.clamp(=0,=100);`\n- **Pass Through:**\n    - Naming the values with its types will pass it into the function!\n    - `set set_number(u32): do.clamp(min:u32,max:u32);`\n    - `get get_number() -\u003e bool: static.clamp(min:u32,max:u32);`\n```rust\n// Advanced Usage \ntycell!{ u32 {\n    static u32: once_read;\n    set set_raw();\n    set set_by_methods(u32): do.clamp(=0,=100);\n    set set_pass(u32): do.clamp(min:u32,max:u32);\n    get get_raw();\n    get get_by_methods() -\u003e u32: static.add(=5);\n    get get_pass() -\u003e u32: static.add(val:u32);\n}}\n// Sets value to 1000.clamp(0,123) = 123\nu32::set_pass(1000,0,123); \n// Gets 123.add(5) = 128\nassert_eq!(128,u32::get_by_methods());\n```\n## 🧊 Constant\nYou can also set const values!\n```rust\n// Constant\ntycell!{ u32 {\n    const u32 = 100;\n    get number();\n}}\n// Gets 10!\nassert_eq!(10,u32::number());\n```\n\n## 👹 Risky Mutable Options\n⚠`Only use this if you're sure there are no race conditions (or they don't matter) or for debug purposes!`\u003cbr\u003e\nTo make the static value mutable, use `once_write` or `lazy_write`.\n```rust\n// Risky Mutable\ntycell!{ u32 {\n    static u32: risky_write;\n    set set_number();\n    get number();\n}}\n// Set it somewhere once:\nu32::set_number(5u32);\n// Default getter is mutable already\n*u32::number() = 10;\n// Gets 10!\nassert_eq!(10,*u32::number());\n```\n\n## 🦥 As Lazy Static\nTo create a lazy static value, use the `lazy_read` option and use a block instead of the setter function!\n```rust\n// Lazy Static\ntycell!{ u32 {\n    static HashMap\u003cu32,String\u003e: lazy_read;\n    set {\n        let mut map = HashMap::new();\n        for i in 0..100 {\n            map.insert(i,i.to_string());\n        }\n        map\n    }\n    get get_lazy_map();\n    get get_lazy() -\u003e Option\u003c\u0026String\u003e: static.get(id:\u0026u32);\n}}\n// Gets Some(\"3\":\u0026String)\nassert_eq!(\u0026\"3\",\u0026u32::get_lazy(\u00263).unwrap());\n```\n## ➡ Simple Mapping\nIf you only need the default getter and setters, there is a short form:\n```rust\n// Simple Usage\ntycell!{\n    // store a vec of bools on the bool type\n    // a single specifier inside [..] will use once_read\n    // adding 'mut' before it sets it to once_write\n    // adding a block {} after the specifier will use lazy_.. instead of once_..\n    bool \u003e Vec\u003cbool\u003e: [bools] [mut more_bools] [lazy_bools{vec![true,false]}];\n    // adding '= value' after the specifier will set a constant value\n    bool \u003e u32: [number=100];\n}\nbool::set_bools([true,false]);\nbool::set_more_bools([true,false]);\n```\nIf you only attach values of the same type as their parent:\n```rust\n// Simplest Usage\ntycell!{\n    // Same as bool \u003e bool: [is_nice];\n    bool: [is_nice];\n}\n```\nIf you want to attach a type to its single generic type, e.g. `u32 \u003e Vec\u003cu32\u003e` you can use `!Vec\u003cu32\u003e`.\u003cbr\u003e\nIncrease the number of `!` to set the level, e.g. `u32 \u003e Vec\u003cVec\u003cu32\u003e\u003e` \u003c=\u003e `!!Vec\u003cVec\u003cu32\u003e\u003e`.\u003cbr\u003e\n```rust\ntycell!{\n    !Vec\u003cbool\u003e:[is_nice];\n}\n```\n\nYou can't mix different types of left-handed syntax, unless wrapped in `{}`\n```rust\n// working\ntycell!{\n    {!Vec\u003cbool\u003e} [is_nice]\n    {bool\u003eVec\u003cbool\u003e} [is_v_nice]\n    {bool} [is_x_nice]\n}\n// NOT working\ntycell!{\n    !Vec\u003cbool\u003e: [is_nice];\n    bool\u003eVec\u003cbool\u003e: [is_v_nice];\n    bool: [is_x_nice];\n}\n```\n\nYou can also chain methods for the getter and adjust its return type.\n```rust\ntycell!{\n    {String} \n        [clone_str.clone()-\u003eString] \n        [clone_lazy_str.clone()-\u003eString{\"test\"}]\n}\n```\n\n## ➡ Simple (Hash)Maps and Vecs\nEase up getting values from a HasmMap-esque types, by using \u003ckey\u003e after the name.\u003cbr\u003e\nif no key is provided, the type is set to a Vec\u003c..\u003e instead.\n```rust\n// uses anythng named TyMap for flaxibility\nuse std::collections::HashMap as TyMap;\ntycell!{\n    // same as above, but \u003ckeytype\u003e after the specifier\n    bool \u003e bool: [bools\u003cu8\u003e] [mut more_bools\u003cu8\u003e] [lazy_bools\u003cu8\u003e{[(1,true)]}];\n}\nbool::set_bools([(1,true)]);\nbool::set_more_bools([(1,true)]);\n```\n## 🔗 Related Projects\n- \u003ca href=\"https://crates.io/crates/bevy_cell\"\u003ebevy_cell\u003c/a\u003e - Attach bevy Handle and Entity to types.\n---\n### License\n\u003csup\u003e\nLicensed under either of \u003ca href=\"LICENSE-APACHE\"\u003eApache License, Version\n2.0\u003c/a\u003e or \u003ca href=\"LICENSE-MIT\"\u003eMIT license\u003c/a\u003e at your option.\n\u003c/sup\u003e\n\u003cbr\u003e\n\u003csub\u003e\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in this crate by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n\u003c/sub\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdekirisu%2Ftype_cell","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdekirisu%2Ftype_cell","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdekirisu%2Ftype_cell/lists"}