{"id":16679328,"url":"https://github.com/fujiapple852/bounded-static","last_synced_at":"2025-04-10T03:53:20.622Z","repository":{"id":38246894,"uuid":"459095688","full_name":"fujiapple852/bounded-static","owner":"fujiapple852","description":"A Rust crate that defines the ToBoundedStatic and IntoBoundedStatic traits","archived":false,"fork":false,"pushed_at":"2025-03-15T07:43:41.000Z","size":101,"stargazers_count":16,"open_issues_count":4,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-10T03:53:18.321Z","etag":null,"topics":["copy-on-write","data-structures","derive-macro","memory-management","rust","rust-library","rust-lifetime","rust-patterns"],"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/fujiapple852.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2022-02-14T09:30:34.000Z","updated_at":"2025-04-09T10:20:42.000Z","dependencies_parsed_at":"2022-09-26T18:11:18.298Z","dependency_job_id":"c56f724a-8844-46e2-9b85-8104206eef07","html_url":"https://github.com/fujiapple852/bounded-static","commit_stats":{"total_commits":130,"total_committers":4,"mean_commits":32.5,"dds":0.05384615384615388,"last_synced_commit":"ab9619a213b7c54ebb33d6fd4c66655c84bd2cb2"},"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fujiapple852%2Fbounded-static","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fujiapple852%2Fbounded-static/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fujiapple852%2Fbounded-static/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fujiapple852%2Fbounded-static/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fujiapple852","download_url":"https://codeload.github.com/fujiapple852/bounded-static/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248154998,"owners_count":21056542,"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":["copy-on-write","data-structures","derive-macro","memory-management","rust","rust-library","rust-lifetime","rust-patterns"],"created_at":"2024-10-12T13:34:46.390Z","updated_at":"2025-04-10T03:53:20.598Z","avatar_url":"https://github.com/fujiapple852.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"![ci](https://github.com/fujiapple852/bounded-static/actions/workflows/ci.yml/badge.svg)\n[![Documentation](https://docs.rs/bounded-static/badge.svg)](https://docs.rs/bounded-static/0.8.0)\n[![Crate](https://img.shields.io/crates/v/bounded-static.svg)](https://crates.io/crates/bounded-static/0.8.0)\n\n# Bounded Static\nThis crate defines the [`ToBoundedStatic`](https://docs.rs/bounded-static/0.8.0/bounded_static/trait.ToBoundedStatic.html) \nand [`IntoBoundedStatic`](https://docs.rs/bounded-static/0.8.0/bounded_static/trait.IntoBoundedStatic.html) traits, \nthe [`ToStatic`](https://docs.rs/bounded-static/0.8.0/bounded_static/derive.ToStatic.html) macro and provides impls \nfor common types.  This crate has zero-dependencies, is `no_std` friendly and \nforbids `unsafe` code.\n\nAs described in\nthe [Common Rust Lifetime Misconceptions](https://github.com/pretzelhammer/rust-blog/blob/master/posts/common-rust-lifetime-misconceptions.md#2-if-t-static-then-t-must-be-valid-for-the-entire-program):\n\n\u003e `T: 'static` should be read as _\"`T` is bounded by a `'static` lifetime\"_ not _\"`T` has a `'static` lifetime\"_.\n\nThe traits `ToBoundedStatic` and `IntoBoundedStatic` can be used to convert any suitable `T` and `\u0026T` to an\nowned `T` such that `T: 'static`.  Both traits define an associated type which is bounded by `'static` and provide a \nmethod to convert to that bounded type.\n\nThe macros `ToStatic` can be used to automatically derive `ToBoundedStatic` and `IntoBoundedStatic` for any `struct` \nor `enum` that can be converted to a form that is bounded by `'static`.\n\nRefer to the crate [`documentation`](https://docs.rs/bounded-static/0.8.0/bounded_static) for details and examples.\n\n## FAQ\n\n### When is this useful?\n\nThis is useful for data structures which directly or indirectly contain `Cow\u003cT\u003e` types that must be supplied to \na function which requires the `'static` bound (i.e. [`std::thread::spawn`](https://doc.rust-lang.org/std/thread/fn.spawn.html)):\n\n```rust\n#[derive(Debug, PartialEq, ToStatic)]\nstruct Foo\u003c'a\u003e {\n    foo: Cow\u003c'a, str\u003e,\n    bar: Vec\u003cBar\u003c'a\u003e\u003e\n}\n#[derive(Debug, PartialEq, ToStatic)]\nenum Bar\u003c'a\u003e {\n    First,\n    Second(Cow\u003c'a, str\u003e),\n}\n\nfn main() {\n    let value = String::from(\"data\");\n    let foo = Foo {\n        foo: Cow::from(\u0026value),\n        bar: vec![Bar::First, Bar::Second(Cow::from(\u0026value))]\n    };\n    let foo_static = foo.into_static();\n    std::thread::spawn(move || {\n        assert_eq!(foo_static.foo, \"data\");\n        assert_eq!(foo_static.bar, vec![Bar::First, Bar::Second(\"data\".into())])\n    }).join().unwrap();\n}\n```\n\n### How does this differ from the `ToOwned` trait?\n\nThe [`ToOwned`](https://doc.rust-lang.org/std/borrow/trait.ToOwned.html) trait defines an associated type `Owned` which\nis not bound by `'static` and therefore the follow will not compile:\n\n```rust\nuse std::borrow::Cow;\n\nfn main() {\n    #[derive(Clone)]\n    struct Foo\u003c'a\u003e {\n        foo: Cow\u003c'a, str\u003e,\n    }\n\n    fn ensure_static\u003cT: 'static\u003e(_: T) {}\n\n    let s = String::from(\"data\");\n    let foo = Foo { foo: Cow::from(\u0026s) };\n    ensure_static(foo.to_owned())\n}\n```\n\nResults in the following error:\n\n```\nerror[E0597]: `s` does not live long enough\n  --\u003e src/lib.rs:12:36\n   |\n12 |     let foo = Foo { foo: Cow::from(\u0026s) };\n   |                          ----------^^-\n   |                          |         |\n   |                          |         borrowed value does not live long enough\n   |                          argument requires that `s` is borrowed for `'static`\n13 |     ensure_static(foo.to_owned())\n14 | }\n   | - `s` dropped here while still borrowed\n```\n\nReplacing `Clone` with `ToStatic` and using `into_static()` (or `to_static()` as needed) allows the example to compile:\n\n```rust\nuse std::borrow::Cow;\n\nfn main() {\n\n    #[derive(ToStatic)]\n    struct Foo\u003c'a\u003e {\n        foo: Cow\u003c'a, str\u003e,\n    }\n\n    fn ensure_static\u003cT: 'static\u003e(_: T) {}\n\n    let s = String::from(\"data\");\n    let foo = Foo { foo: Cow::from(\u0026s) };\n    ensure_static(foo.into_static())\n}\n```\n\n## License\n\n`bounded-static` is distributed under the terms of the Apache License (Version 2.0).\n\nSee [LICENSE](LICENSE) for details.\n\nCopyright 2022","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffujiapple852%2Fbounded-static","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffujiapple852%2Fbounded-static","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffujiapple852%2Fbounded-static/lists"}