Skip to content

Commit 9149155

Browse files
committed
Update docs for the API changes so far
1 parent 4ea8c15 commit 9149155

File tree

4 files changed

+64
-11
lines changed

4 files changed

+64
-11
lines changed

README.md

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ fn main() {
4646

4747
Target traits must be explicitly designated beforehand. There are three ways of doing it:
4848

49-
## `#[cast_to]` to `impl` item
49+
### `#[cast_to]` to `impl` item
5050
The trait implemented is designated as a target trait.
5151

5252
```rust
@@ -63,7 +63,7 @@ impl Greet for Data {
6363
}
6464
```
6565

66-
## `#[cast_to(Trait)]` to type definition
66+
### `#[cast_to(Trait)]` to type definition
6767
For the type, the traits specified as arguments to the `#[cast_to(...)]` attribute are designated as target traits.
6868

6969
```rust
@@ -82,7 +82,7 @@ impl Greet for Data {
8282
struct Data;
8383
```
8484

85-
## `castable_to!(Type => Trait1, Trait2)`
85+
### `castable_to!(Type => Trait1, Trait2)`
8686
For the type, the traits following `:` are designated as target traits.
8787

8888
```rust
@@ -103,14 +103,22 @@ castable_to!(Data => Greet, std::fmt::Debug);
103103
fn main() {}
104104
```
105105

106+
## `Arc` Support
107+
`std::sync::Arc` is unique in that it implement `downcast` method only on `dyn Any + Send + Sync + 'static'.
108+
To use with `Arc`, the following steps should be taken:
109+
110+
* Mark source traits with [`CastFromSync`] instead of [`CastFrom`]
111+
* Add `[sync]` flag to `#[cast_to]` and `castable_to!` as follows:
112+
```ignore
113+
#[cast_to([sync])]
114+
#[cast_to([sync] Trait1, Trait2)]
115+
castable_to!(Type => [sync] Trait, Trait2);
116+
```
117+
106118
# How it works
107119
First of all, [`CastFrom`] trait makes it possible to retrieve an object of [`std::any::Any`]
108120
from an object for a sub-trait of [`CastFrom`].
109121

110-
> [`CastFrom`] will become obsolete and be replaced with [`std::any::Any`]
111-
> once [unsized coercion](https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions)
112-
> from a trait object to another trait object for its super-trait is implemented in the stable Rust.
113-
114122
And the macros provided by `intertrait` generates trampoline functions for downcasting a trait object
115123
for [`std::any::Any`] back to its concrete type and then creating a trait object for the target trait from it.
116124

@@ -143,4 +151,5 @@ dual licensed as above, without any additional terms or conditions.
143151

144152
[`std::any::Any`]: https://doc.rust-lang.org/std/any/trait.Any.html
145153
[`TypeId`]: https://doc.rust-lang.org/std/any/struct.TypeId.html
146-
[`CastFrom`]: https://docs.rs/intertrait/*/intertrait/trait.CastFrom.html
154+
[`CastFrom`]: https://docs.rs/intertrait/*/intertrait/trait.CastFrom.html
155+
[`CastFromSync`]: https://docs.rs/intertrait/*/intertrait/trait.CastFromSync.html

macros/src/lib.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ mod item_type;
1717
/// If on an `impl` item, no argument is allowed. But on a type definition, the target traits
1818
/// must be listed explicitly.
1919
///
20+
/// Add `[sync]` before the list of traits if the underlying type is `Sync + Send` and you
21+
/// need `std::sync::Arc`.
22+
///
2023
/// # Examples
2124
/// ## On a trait impl
2225
/// ```
@@ -43,6 +46,15 @@ mod item_type;
4346
/// #[derive(std::fmt::Debug)]
4447
/// struct Data;
4548
/// ```
49+
///
50+
/// ## For Arc
51+
/// Use when the underlying type is `Sync + Send` and you want to use `Arc`.
52+
/// ```
53+
/// // Debug can be cast into from any sub-trait of CastFrom implemented by Data
54+
/// #[cast_to([sync] std::fmt::Debug)]
55+
/// #[derive(std::fmt::Debug)]
56+
/// struct Data;
57+
/// ```
4658
#[proc_macro_attribute]
4759
pub fn cast_to(args: TokenStream, input: TokenStream) -> TokenStream {
4860
match parse::<Targets>(args) {
@@ -60,7 +72,7 @@ pub fn cast_to(args: TokenStream, input: TokenStream) -> TokenStream {
6072
.into()
6173
}
6274

63-
/// Declare target traits for casting implemented by a type.
75+
/// Declares target traits for casting implemented by a type.
6476
///
6577
/// This macro is for registering both a concrete type and its traits to be targets for casting.
6678
/// Useful when the type definition and the trait implementations are in an external crate.
@@ -84,6 +96,23 @@ pub fn cast_to(args: TokenStream, input: TokenStream) -> TokenStream {
8496
/// }
8597
/// castable_to! { Data => std::fmt::Debug, Greet }
8698
/// ```
99+
///
100+
/// When the type is `Sync + Send` and is used with `Arc`:
101+
/// ```
102+
/// #[derive(std::fmt::Debug)]
103+
/// enum Data {
104+
/// A, B, C
105+
/// }
106+
/// trait Greet {
107+
/// fn greet(&self);
108+
/// }
109+
/// impl Greet for Data {
110+
/// fn greet(&self) {
111+
/// println!("Hello");
112+
/// }
113+
/// }
114+
/// castable_to! { Data => [sync] std::fmt::Debug, Greet }
115+
/// ```
87116
#[proc_macro]
88117
pub fn castable_to(input: TokenStream) -> TokenStream {
89118
let Casts {

src/cast.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
//! `cast` module contains traits to provide `cast` method for various references
2+
//! and smart pointers.
3+
//!
4+
//! In source files requiring casts, import all of the traits as follows:
5+
//!
6+
//! ```ignore
7+
//! use intertrait::cast::*;
8+
//! ```
9+
//!
10+
//! Since there exists single trait for each receiver type, the same `cast` method is overloaded.
111
mod cast_arc;
212
mod cast_box;
313
mod cast_mut;

src/lib.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! A library providing direct casting among trait objects implemented by a type.
22
//!
3-
//! In Rust, an object of a sub-trait of [`std::any::Any`] can be downcast to a concrete type
3+
//! In Rust, an object of a sub-trait of [`Any`] can be downcast to a concrete type
44
//! at runtime if the type is known. But no direct casting between two trait objects
55
//! (i.e. without involving the concrete type of the backing value) are possible
66
//! (even no coercion from a trait object to that of its super-trait yet).
@@ -45,14 +45,19 @@
4545
//! * [`#[cast_to(Trait)]`][cast_to] to type definition
4646
//! * [`castable_to!(Type => Trait1, Trait2)`][castable_to]
4747
//!
48-
//! Refer to the documents for each of macros for details.
48+
//! If the underlying type involved is `Sync + Send` and you want to use it with [`Arc`],
49+
//! use [`CastFromSync`] in place of [`CastFrom`] and add `[sync]` flag before the list
50+
//! of traits in the macros. Refer to the documents for each of macros for details.
4951
//!
5052
//! For casting, refer to traits defined in [`cast`] module.
5153
//!
5254
//! [cast_to]: ./attr.cast_to.html
5355
//! [castable_to]: ./macro.castable_to.html
56+
//! [`CastFrom`]: ./trait.CastFrom.html
57+
//! [`CastFromSync`]: ./trait.CastFromSync.html
5458
//! [`cast`]: ./cast/index.html
5559
//! [`Any`]: https://doc.rust-lang.org/std/any/trait.Any.html
60+
//! [`Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html
5661
use std::any::{Any, TypeId};
5762
use std::collections::HashMap;
5863
use std::rc::Rc;

0 commit comments

Comments
 (0)