|
1 | | -# InterTrait |
| 1 | +# Intertrait |
2 | 2 |
|
3 | 3 |  |
4 | 4 | [](https://crates.io/crates/intertrait) |
5 | 5 | [](https://docs.rs/intertrait) |
6 | 6 |
|
7 | 7 | This library provides direct casting among trait objects implemented by a type. |
8 | 8 |
|
9 | | -In Rust, an object of a sub-trait of [`std::any::Any`] can be downcast to a concrete type at runtime if the type is known. But no direct casting between two trait objects (i.e. without involving the concrete type of the backing value) are possible (even no coercion from a trait object to that of its super-trait yet). |
| 9 | +In Rust, a trait object for a sub-trait of [`std::any::Any`] can be downcast to a concrete type at runtime |
| 10 | +if the type is known. But no direct casting between two trait objects (i.e. without involving the concrete type |
| 11 | +of the backing value) are possible (even no coercion from a trait object for a trait to that for its super-trait yet). |
10 | 12 |
|
11 | | -With this crate, any trait object with [`CastFrom`] as its super-trait can be cast directly to another trait object implemented by the underlying type if the target traits are registered beforehand with the macros provided by this crate. |
| 13 | +With this crate, any trait object for a sub-trait of [`CastFrom`] can be cast directly to a trait object |
| 14 | +for another trait implemented by the underlying type if the target traits are registered beforehand |
| 15 | +with the macros provided by this crate. |
12 | 16 |
|
13 | 17 | # Usage |
14 | 18 | ```rust |
@@ -39,7 +43,7 @@ fn main() { |
39 | 43 | } |
40 | 44 | ``` |
41 | 45 |
|
42 | | -Target traits must be explicitly designated beforehand. There are three ways to do it: |
| 46 | +Target traits must be explicitly designated beforehand. There are three ways of doing it: |
43 | 47 |
|
44 | 48 | ## `#[cast_to]` to `impl` item |
45 | 49 | The trait implemented is designated as a target trait. |
@@ -92,18 +96,28 @@ fn main() {} |
92 | 96 | ``` |
93 | 97 |
|
94 | 98 | # How it works |
95 | | -First of all, [`CastFrom`] trait makes it possible to retrieve an object of [`std::any::Any`] from an object of a sub-trait of [`CastFrom`]. |
| 99 | +First of all, [`CastFrom`] trait makes it possible to retrieve an object of [`std::any::Any`] |
| 100 | +from an object for a sub-trait of [`CastFrom`]. |
96 | 101 |
|
97 | | -> [`CastFrom`] will become obsolete and be replaced with [`std::any::Any`] once the [unsized coercion](https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions) from a trait object to an object of its super-trait is implemented in the stable Rust. |
| 102 | +> [`CastFrom`] will become obsolete and be replaced with [`std::any::Any`] |
| 103 | +> once [unsized coercion](https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions) |
| 104 | +> from a trait object to another trait object for its super-trait is implemented in the stable Rust. |
98 | 105 |
|
99 | | -And the macros provided by `intertrait` generates trampoline functions for downcasting a trait object of [`std::any::Any`] back to its concrete type and then creating the target trait object from it. |
| 106 | +And the macros provided by `intertrait` generates trampoline functions for downcasting a trait object |
| 107 | +for [`std::any::Any`] back to its concrete type and then creating a trait object for the target trait from it. |
100 | 108 |
|
101 | | -Those trampoline functions are aggregated into a global registry using [`linkme`](https://github.com/dtolnay/linkme/) crate, which involves no (generally discouraged) life-before-main trick. The registry is keyed with a pair of [`TypeId`]s, which are for the concrete type backing an object of a sub-trait of [`CastFrom`] and the target trait (the actual implementation is a bit different here, but conceptually so). |
| 109 | +Those trampoline functions are aggregated into a global registry |
| 110 | +using [`linkme`](https://github.com/dtolnay/linkme/) crate, which involves no (generally discouraged) |
| 111 | +life-before-main trick. The registry is keyed with a pair of [`TypeId`]s, which are those of the concrete type |
| 112 | +backing a trait object for a sub-trait of [`CastFrom`] and the target trait (the actual implementation |
| 113 | +is a bit different here, but conceptually so). |
102 | 114 |
|
103 | | -In the course, it doesn't rely on any unstable Rust implementation details such as the layout of trait objects that may be changed in the future. |
| 115 | +In the course, it doesn't rely on any unstable Rust implementation details such as the layout of trait objects |
| 116 | +that may be changed in the future. |
104 | 117 |
|
105 | 118 | # Credits |
106 | | -`intertrait` has taken much of its core ideas from the great [`traitcast`](https://github.com/bch29/traitcast) crate. This crate enhances mainly in the ergonomics. |
| 119 | +`intertrait` has taken much of its core ideas from the great [`traitcast`](https://github.com/bch29/traitcast) crate. |
| 120 | +This crate enhances mainly in the ergonomics. |
107 | 121 |
|
108 | 122 | # License |
109 | 123 | Licensed under either of |
|
0 commit comments