{"id":21497303,"url":"https://github.com/jazzfool/uniq","last_synced_at":"2025-07-25T00:18:38.595Z","repository":{"id":137122588,"uuid":"258691536","full_name":"jazzfool/uniq","owner":"jazzfool","description":"ID-based event dispatcher","archived":false,"fork":false,"pushed_at":"2020-07-01T13:44:22.000Z","size":24,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-03-17T12:26:16.337Z","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":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jazzfool.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":"2020-04-25T05:02:58.000Z","updated_at":"2021-12-23T05:35:05.000Z","dependencies_parsed_at":null,"dependency_job_id":"d4ab374b-cb25-49fd-9b74-03f65ec4f3ef","html_url":"https://github.com/jazzfool/uniq","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jazzfool/uniq","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jazzfool%2Funiq","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jazzfool%2Funiq/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jazzfool%2Funiq/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jazzfool%2Funiq/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jazzfool","download_url":"https://codeload.github.com/jazzfool/uniq/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jazzfool%2Funiq/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261846063,"owners_count":23218701,"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-11-23T16:23:04.585Z","updated_at":"2025-06-25T09:38:54.981Z","avatar_url":"https://github.com/jazzfool.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Uniq\n\nUnique application-wide queue adapter through strongly-typed event identification.\n\n```rust\n// A thread-safe variant also exists; `arc::Queue`.\nlet q = rc::Queue::new();\n// The ID type is generic, but it defaults to `u64`.\n\nlet mut l1 = q.listen::\u003c()\u003e()\n    .and_on(0, |_, _event: \u0026ClickEvent| {\n        println!(\"listener 1 observed a click from id 0\");\n    })\n    .and_on(5, |_, _event: \u0026WindowEvent| {\n        println!(\"listener 1 observed a window event from id 5\");\n    });\n\nlet mut l2 = q.listen::\u003cWrite\u003ci32\u003e\u003e()\n    .and_on(3, |n: \u0026mut i32, _event: \u0026NetworkEvent| {\n        *n += 1;\n        println!(\"listener 2 observed a network event from id 3\");\n    })\n    .and_on(2, |_, _event: \u0026NetworkEvent| {\n        println!(\"listener 2 observed a network event from id 2\");\n    });\n\nq.emit_owned(0, ClickEvent);\nq.emit_owned(2, NetworkEvent);\nq.emit_owned(3, NetworkEvent);\nq.emit_owned(5, WindowEvent);\n\nl1.dispatch(\u0026mut ());\nl2.dispatch(\u0026mut 0);\n```\n\nThe first parameter of the event handlers is an arbitrary mutable object that can be passed to handler code. The type of this parameter is homogenous intra-listener and heterogenous inter-listener.\n\nNotice that the second listener is able to distinguish `NetworkEvents` coming from two difference sources.\n\nThis mutable object can be a tuple of `Read`/`Write`s so that you can pass multiple mutable or immutable references:\n```rust\nlet mut l = q.listen::\u003c(Write\u003cFoo\u003e, Read\u003cFooBar\u003e, Write\u003cBar\u003e)\u003e()\n    .and_on(0, |_: \u0026mut (\u0026mut Foo, \u0026FooBar, \u0026mut Bar), _event: \u0026Event| { /* ... */ });\n\nlet mut foo = Foo::new();\nlet foo_bar = FooBar::new();\nlet mut bar = Bar::new();\n\nl.dispatch(\u0026mut foo, \u0026foo_bar, \u0026mut bar);\n```\n\nThere is no limit on the permutation of the `Read`/`Writes`, however only a total of 10 is permitted. This can easily be increased if need be (open an issue), but realistically, it's unlikely you'll need more.\n\nThere's a simple additional utility module; `uniq::id`, which will atomically generate a globally unique ID. This is useful for typical applications of `uniq`.\n\nFor example, each widget in a UI may have a unique ID, hence allowing multiple widgets of the same type to distinguish the events they emit. The alternative to\nthis is to have an event queue for each widget, but having multiple event queue is known to cause event ordering problems.\n\n```rust\n// `next()` can be invoked from any thread.\n\nlet id_1 = uniq::id::next();\nlet id_2 = uniq::id::next();\n\nassert_ne!(id_1, id_2);\n```\n\nThis crate is based on `reclutch-nursery/even2` and `jazzfool/sinq`, and is somewhat of a combination of them.\n\n## License\n\nUniq is licensed under either\n\n- [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0)\n- [MIT](http://opensource.org/licenses/MIT)\n\nat your choosing.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjazzfool%2Funiq","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjazzfool%2Funiq","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjazzfool%2Funiq/lists"}