{"id":13822295,"url":"https://github.com/CodeChain-io/intertrait","last_synced_at":"2025-05-16T15:33:50.194Z","repository":{"id":47697988,"uuid":"244837836","full_name":"CodeChain-io/intertrait","owner":"CodeChain-io","description":"A library providing direct casting among trait objects implemented by a type","archived":false,"fork":false,"pushed_at":"2022-10-26T09:07:10.000Z","size":94,"stargazers_count":38,"open_issues_count":3,"forks_count":4,"subscribers_count":11,"default_branch":"master","last_synced_at":"2024-04-24T01:02:39.619Z","etag":null,"topics":[],"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/CodeChain-io.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}},"created_at":"2020-03-04T07:43:42.000Z","updated_at":"2024-04-20T21:50:55.000Z","dependencies_parsed_at":"2022-09-07T08:22:47.755Z","dependency_job_id":null,"html_url":"https://github.com/CodeChain-io/intertrait","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeChain-io%2Fintertrait","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeChain-io%2Fintertrait/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeChain-io%2Fintertrait/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeChain-io%2Fintertrait/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CodeChain-io","download_url":"https://codeload.github.com/CodeChain-io/intertrait/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225436637,"owners_count":17474185,"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-08-04T08:01:53.067Z","updated_at":"2024-11-19T22:32:54.043Z","avatar_url":"https://github.com/CodeChain-io.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"# Intertrait\n\n![Build Status](https://github.com/CodeChain-io/intertrait/workflows/ci/badge.svg)\n[![Latest Version](https://img.shields.io/crates/v/intertrait.svg)](https://crates.io/crates/intertrait)\n[![Rust Documentation](https://img.shields.io/badge/api-rustdoc-blue.svg)](https://docs.rs/intertrait)\n\nThis library provides direct casting among trait objects implemented by a type.\n\nIn Rust, a trait object for a sub-trait of [`std::any::Any`] can be downcast to a concrete type at runtime\nif the type is known. But no direct casting between two trait objects (i.e. without involving the concrete type\nof the backing value) is possible (even no coercion from a trait object for a trait to that for its super-trait yet).\n\nWith this crate, any trait object for a sub-trait of [`CastFrom`] can be cast directly to a trait object\nfor another trait implemented by the underlying type if the target traits are registered beforehand\nwith the macros provided by this crate.\n\n# Dependencies\nAdd the following two dependencies to your `Cargo.toml`:\n\n```toml\n[dependencies]\nintertrait = \"0.2\"\nlinkme = \"0.2\"\n```\n\nThe `linkme` dependency is required due to the use of `linkme` macro in the output of `intertrait` macros.\n\n# Usage\n\n```rust\nuse intertrait::*;\nuse intertrait::cast::*;\n\nstruct Data;\n\ntrait Source: CastFrom {}\n\ntrait Greet {\n    fn greet(\u0026self);\n}\n\n#[cast_to]\nimpl Greet for Data {\n    fn greet(\u0026self) {\n        println!(\"Hello\");\n    }\n}\n\nimpl Source for Data {}\n\nfn main() {\n    let data = Data;\n    let source: \u0026dyn Source = \u0026data;\n    let greet = source.cast::\u003cdyn Greet\u003e();\n    greet.unwrap().greet();\n}\n```\n\nTarget traits must be explicitly designated beforehand. There are three ways of doing it:\n\n### `#[cast_to]` to `impl` item\nThe trait implemented is designated as a target trait.\n\n```rust\nuse intertrait::*;\n\nstruct Data;\ntrait Greet { fn greet(\u0026self); }\n\n#[cast_to]\nimpl Greet for Data {\n    fn greet(\u0026self) {\n        println!(\"Hello\");\n    }\n}\n```\n\n### `#[cast_to(Trait)]` to type definition\nFor the type, the traits specified as arguments to the `#[cast_to(...)]` attribute are designated as target traits.\n\n```rust\nuse intertrait::*;\n\ntrait Greet { fn greet(\u0026self); }\n\nimpl Greet for Data {\n    fn greet(\u0026self) {\n        println!(\"Hello\");\n    }\n}\n\n#[cast_to(Greet, std::fmt::Debug)]\n#[derive(std::fmt::Debug)]\nstruct Data;\n```\n\n### `castable_to!(Type =\u003e Trait1, Trait2)`\nFor the type, the traits following `:` are designated as target traits.\n\n```rust\nuse intertrait::*;\n\n#[derive(std::fmt::Debug)]\nstruct Data;\ntrait Greet { fn greet(\u0026self); }\nimpl Greet for Data {\n    fn greet(\u0026self) {\n        println!(\"Hello\");\n    }\n}\n// Only in an item position due to the current limitation in the stable Rust.\n// https://github.com/rust-lang/rust/pull/68717\ncastable_to!(Data =\u003e Greet, std::fmt::Debug);\n\nfn main() {}\n```\n\n## `Arc` Support\n`std::sync::Arc` is unique in that it implements `downcast` method only on `dyn Any + Send + Sync + 'static'.\nTo use with `Arc`, the following steps should be taken:\n\n* Mark source traits with [`CastFromSync`] instead of [`CastFrom`]\n* Add `[sync]` flag to `#[cast_to]` and `castable_to!` as follows:\n  ```ignore\n  #[cast_to([sync])]\n  #[cast_to([sync] Trait1, Trait2)]\n  castable_to!(Type =\u003e [sync] Trait, Trait2);\n  ```\n\n# How it works\nFirst of all, [`CastFrom`] trait makes it possible to retrieve an object of [`std::any::Any`]\nfrom an object for a sub-trait of [`CastFrom`]. \n\nAnd the macros provided by `intertrait` generates trampoline functions for downcasting a trait object\nfor [`std::any::Any`] back to its concrete type and then creating a trait object for the target trait from it.\n\nThose trampoline functions are aggregated into a global registry\nusing [`linkme`](https://github.com/dtolnay/linkme/) crate, which involves no (generally discouraged)\nlife-before-main trick. The registry is keyed with a pair of [`TypeId`]s, which are those of the concrete type\nbacking a trait object for a sub-trait of [`CastFrom`] and the target trait (the actual implementation\nis a bit different here, but conceptually so).\n\nIn the course, it doesn't rely on any unstable Rust implementation details such as the layout of trait objects\nthat may be changed in the future.\n\n# Credits\n`intertrait` has taken much of its core ideas from the great [`traitcast`](https://github.com/bch29/traitcast) crate.\n\n# License\nLicensed under either of\n\n * Apache License, Version 2.0\n   ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)\n * MIT license\n   ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)\n\nat your option.\n\n## Contribution\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall be\ndual licensed as above, without any additional terms or conditions.\n\n[`std::any::Any`]: https://doc.rust-lang.org/std/any/trait.Any.html\n[`TypeId`]: https://doc.rust-lang.org/std/any/struct.TypeId.html\n[`CastFrom`]: https://docs.rs/intertrait/*/intertrait/trait.CastFrom.html\n[`CastFromSync`]: https://docs.rs/intertrait/*/intertrait/trait.CastFromSync.html","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FCodeChain-io%2Fintertrait","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FCodeChain-io%2Fintertrait","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FCodeChain-io%2Fintertrait/lists"}