{"id":22292675,"url":"https://github.com/rustyyato/pui-old","last_synced_at":"2025-03-25T21:47:09.757Z","repository":{"id":134804529,"uuid":"263202771","full_name":"RustyYato/pui-old","owner":"RustyYato","description":null,"archived":false,"fork":false,"pushed_at":"2020-12-31T20:08:45.000Z","size":149,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-30T19:16:45.425Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/RustyYato.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"MIT-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":"2020-05-12T01:40:14.000Z","updated_at":"2021-01-03T03:34:40.000Z","dependencies_parsed_at":null,"dependency_job_id":"814297ee-0184-4b95-bdd3-24471a8c31bb","html_url":"https://github.com/RustyYato/pui-old","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RustyYato%2Fpui-old","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RustyYato%2Fpui-old/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RustyYato%2Fpui-old/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RustyYato%2Fpui-old/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RustyYato","download_url":"https://codeload.github.com/RustyYato/pui-old/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245550540,"owners_count":20633872,"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":[],"created_at":"2024-12-03T17:23:22.163Z","updated_at":"2025-03-25T21:47:09.730Z","avatar_url":"https://github.com/RustyYato.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pui\n\n[documentation](https://docs.rs/pui)\n\nA set of process unique identifiers that can be used to\nidentify types with minimal overhead within a single process\n\n### features\n\n* `std` (default) - if you have the `std` feature on, it will supercede the `alloc` feature.\n    This allows you to use:\n     * `std` types to implement various traits, for example `Box\u003cI\u003e` will implemnt `Identifier` `I`\n     * `thread_local` types (from the `*_tl`)\n     * `make_global_reuse` (this requires internal locking using a `Mutex`)\n\n* `alloc` - this allows you to use without pulling in all of `std`:\n     * `alloc` types to implement various traits, for example `Box\u003cI\u003e` will implemnt `Identifier` `I`\n\n* `nightly` -  this allows you to use:\n     * atomics on `no_std` targets that don't support 64-bit atomics\n\n### synopsis\n\nYou are guaranteed that two instances of `Identifier` identifier will *never* compare equal\nYou can also create a cheap handle to the identifier, which you can use to mark other types\nas logically owned by the identifier.\n\nFor example, this pattern is sound\n\n```rust\nuse pui::Identifier;\nuse std::cell::UnsafeCell;\n\nstruct Owner\u003cI\u003e {\n    ident: I,\n}\n\nstruct Handle\u003cH, T: ?Sized\u003e {\n    handle: H,\n    value: UnsafeCell\u003cT\u003e,\n}\n\nimpl\u003cH, T\u003e Handle\u003cH, T\u003e {\n    pub fn new(handle: H, value: T) -\u003e Self {\n        Self { handle, value: UnsafeCell::new(value) }\n    }\n}\n\nimpl\u003cI\u003e Owner\u003cI\u003e {\n    pub fn new(ident: I) -\u003e Self {\n        Self { ident }\n    }\n}\n\nimpl\u003cI: Identifier\u003e Owner\u003cI\u003e {\n    pub fn read\u003c'a, T: ?Sized\u003e(\u0026'a self, handle: \u0026'a Handle\u003cI::Handle, T\u003e) -\u003e \u0026'a T {\n        assert!(self.ident.owns(\u0026handle.handle));\n        \n        // This is safe because `ident` owns the `handle`, which means that `self`\n        // is the only `Owner` that could shared access the underlying value\n        // This is because:\n        //  * the `Owner` owns the `Identifier`\n        //  * when we read/write, we bind the lifetime of `self` and `Handle` to the lifetime of\n        //      the output reference\n        //  * we have shared access to `*self`\n        \n        unsafe { \u0026*handle.value.get() }\n    }\n\n    pub fn write\u003c'a, T: ?Sized\u003e(\u0026'a mut self, handle: \u0026'a Handle\u003cI::Handle, T\u003e) -\u003e \u0026'a mut T {\n        assert!(self.ident.owns(\u0026handle.handle));\n        \n        // This is safe because `ident` owns the `handle`, which means that `self`\n        // is the only `Owner` that could exclusive access the underlying value\n        // This is because:\n        //  * the `Owner` owns the `Identifier`\n        //  * when we read/write, we bind the lifetime of `self` and `Handle` to the lifetime of\n        //      the output reference\n        //  * we have exclusive access to `*self`\n        \n        unsafe { \u0026mut *handle.value.get() }\n    }\n}\n```\n\nYou can also use this for safe unchecked accesses\n\n```rust\npub struct Slice\u003c'a, T, I\u003e {\n    data: \u0026'a [T],\n    ident: I,\n}\n\npub struct Idx\u003cH\u003e {\n    index: usize,\n    handle: H,\n}\n\nimpl\u003c'a, T, I: Identifier\u003e Slice\u003c'a, T, I\u003e {\n    fn from_ref(data: \u0026'a [T], ident: I) -\u003e Self {\n        Self { data, ident }\n    }\n\n    pub fn get_indicies\u003c'b\u003e(\u0026self) -\u003e impl 'b + Iterator\u003cItem = Idx\u003cI::Handle\u003e\u003e\n    where\n        I::Handle: 'b,\n    {\n        (0..self.data.len())\n            .zip(std::iter::repeat(self.ident.handle()))\n            .map(move |(index, handle)| Idx { index, handle })\n    }\n\n    pub fn contains_index(\u0026self, index: usize) -\u003e Option\u003cIdx\u003cI::Handle\u003e\u003e {\n        if index \u003c self.data.len() {\n            Some(Idx { index, handle: self.ident.handle() })\n        } else {\n            None\n        }\n    }\n}\n\nimpl\u003c'a, T, I: Identifier\u003e std::ops::Index\u003cIdx\u003cI::Handle\u003e\u003e for Slice\u003c'a, T, I\u003e {\n    type Output = T;\n\n    fn index(\u0026self, idx: Idx\u003cI::Handle\u003e) -\u003e \u0026Self::Output {\n        /// This is safe because self owns `Idx\u003cI::Handle\u003e`\n        /// If `I::Handle: Trivial`, then this assert is a no-op\n        assert!(self.ident.owns(\u0026idx.handle));\n        unsafe { self.data.get_unchecked(idx.index) }\n    }\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frustyyato%2Fpui-old","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frustyyato%2Fpui-old","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frustyyato%2Fpui-old/lists"}