{"id":29742503,"url":"https://github.com/loichyan/dynify","last_synced_at":"2025-10-13T23:31:47.016Z","repository":{"id":302949103,"uuid":"1014031614","full_name":"loichyan/dynify","owner":"loichyan","description":"🦕 Add dyn compatible variant to your async trait!","archived":false,"fork":false,"pushed_at":"2025-07-22T05:59:02.000Z","size":122,"stargazers_count":45,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-22T07:47:01.304Z","etag":null,"topics":["async","no-std","rust"],"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/loichyan.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-04T23:08:28.000Z","updated_at":"2025-07-22T05:55:19.000Z","dependencies_parsed_at":null,"dependency_job_id":"b472c026-bd7f-47c1-bf23-1222feb321f4","html_url":"https://github.com/loichyan/dynify","commit_stats":null,"previous_names":["loichyan/dynify"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/loichyan/dynify","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loichyan%2Fdynify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loichyan%2Fdynify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loichyan%2Fdynify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loichyan%2Fdynify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/loichyan","download_url":"https://codeload.github.com/loichyan/dynify/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loichyan%2Fdynify/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267109113,"owners_count":24037616,"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","status":"online","status_checked_at":"2025-07-26T02:00:08.937Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["async","no-std","rust"],"created_at":"2025-07-26T02:43:09.621Z","updated_at":"2025-10-13T23:31:47.011Z","avatar_url":"https://github.com/loichyan.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🦕 dynify\n\n[![crates.io](https://img.shields.io/crates/v/dynify)](https://crates.io/crates/dynify)\n[![docs.rs](https://img.shields.io/docsrs/dynify)](https://docs.rs/dynify)\n[![msrv](https://img.shields.io/crates/msrv/dynify)](https://crates.io/crates/dynify)\n[![build status](https://img.shields.io/github/actions/workflow/status/loichyan/dynify/cicd.yml)](https://github.com/loichyan/dynify/actions)\n[![codecov](https://img.shields.io/codecov/c/gh/loichyan/dynify)](https://codecov.io/gh/loichyan/dynify)\n\nAdd dyn compatible variant to your async trait with dynify!\n\n## ✨ Overview\n\ndynify implements partial features of the experimental\n[in-place initialization proposal](https://github.com/rust-lang/lang-team/issues/336)\nin stable Rust, along with a set of safe APIs for creating in-place constructors\nto initialize trait objects. Here’s a quick example of how to use dynify:\n\n```rust\nuse dynify::Dynify;\nuse std::future::Future;\nuse std::mem::MaybeUninit;\n\n// `AsyncRead` is dyn incompatible :(\n// With dynify, we can create a dyn compatible variant for `AsyncRead` in one line :)\n#[dynify::dynify]\ntrait AsyncRead { // By default, another trait prefixed with `Dyn` is generated.\n    async fn read_to_string(\u0026mut self) -\u003e String;\n}\n\n// Now we can use dynamic dispatched `AsyncRead`!\nasync fn dynamic_dispatch(reader: \u0026mut dyn DynAsyncRead) {\n    let mut stack = [MaybeUninit::\u003cu8\u003e::uninit(); 16];\n    let mut heap = Vec::\u003cMaybeUninit\u003cu8\u003e\u003e::new();\n    // Initialize trait objects on the stack if not too large, otherwise on the heap.\n    let fut = reader.read_to_string().init2(\u0026mut stack, \u0026mut heap);\n    let content = fut.await;\n    // ...\n}\n```\n\nFor a more detailed explanation, check out the\n[API documentation](https://docs.rs/dynify).\n\n## 🔍 Comparisons with other similar projects\n\n### vs pin-init\n\n[pin-init](https://crates.io/crates/pin-init) has been around for a while and\nprovides safe methods for creating in-place constructors for `struct`s. It also\nhas an\n[experimental branch](https://github.com/Rust-for-Linux/pin-init/tree/dev/experimental/dyn)\nthat enables the generation of dyn compatible variants for `async fn`s. The key\ndifference is that pin-init relies on some nightly features, while dynify is\nbuilt with stable Rust. Moreover, as their names suggest, pin-init is focused on\nthe pinned initialization of structures, whereas dynify targets dyn\ncompatibility for functions. With its ongoing `#[dyn_init]` feature, pin-init\ncan be considered as a superset of dynify.\n\n### vs async-trait\n\n[async-trait](https://crates.io/crates/async-trait) is another widely used crate\nfor dynamic dispatch on AFIT (Async Fn In Trait). The main advantage of dynify\nis its ability to allocate trait objects on the stack, making it more suitable\nfor limited environments. In contrast, async-trait requires heap allocation to\nstore trait objects, as it essentially transforms `async fn` into\n`Box\u003cdyn Future\u003e`.\n\n### vs dynosaur\n\n[dynosaur](https://crates.io/crates/dynosaur) employs the same approach as\nasync-trait to generate dyn compatible traits but, by default, preserves the\noriginal trait for more performant static dispatch. Similar to the async-trait\ncase, the main advantage of using dynify is the possibility to achieve heapless\ndynamic dispatch.\n\n## ♥️ Special thanks\n\n- [Rust-for-Linux/pin-init](https://github.com/Rust-for-Linux/pin-init) for its\n  brilliant design on creating constructors for `async fn`s, which serves as the\n  foundation of dynify.\n- [In-place initialization proposal](https://hackmd.io/@aliceryhl/BJutRcPblx)\n  for its excellent design on initializer traits, which is incorporated into\n  several trait designs of dynify.\n- [zjp-CN/dyn-afit](https://github.com/zjp-CN/dyn-afit) for the comprehensive\n  comparisons of community solutions for dynamic dispatch on AFIT, which greatly\n  inspired dynify.\n\n## ⚖️ License\n\nLicensed under either of\n\n- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or\n  \u003chttp://www.apache.org/licenses/LICENSE-2.0\u003e)\n- MIT license ([LICENSE-MIT](LICENSE-MIT) or\n  \u003chttp://opensource.org/licenses/MIT\u003e)\n\nat your option.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Floichyan%2Fdynify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Floichyan%2Fdynify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Floichyan%2Fdynify/lists"}