Vendor things
This commit is contained in:
parent
5deceec006
commit
977e3c17e5
19434 changed files with 10682014 additions and 0 deletions
165
third-party/vendor/downcast-rs/README.md
vendored
Normal file
165
third-party/vendor/downcast-rs/README.md
vendored
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
# downcast-rs
|
||||
|
||||
[](https://github.com/marcianx/downcast-rs/actions)
|
||||
[](https://crates.io/crates/downcast-rs)
|
||||
[](https://docs.rs/downcast-rs)
|
||||
|
||||
Rust enums are great for types where all variations are known beforehand. But a
|
||||
container of user-defined types requires an open-ended type like a **trait
|
||||
object**. Some applications may want to cast these trait objects back to the
|
||||
original concrete types to access additional functionality and performant
|
||||
inlined implementations.
|
||||
|
||||
`downcast-rs` adds this downcasting support to trait objects using only safe
|
||||
Rust. It supports **type parameters**, **associated types**, and **constraints**.
|
||||
|
||||
## Usage
|
||||
|
||||
Add the following to your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
downcast-rs = "1.2.0"
|
||||
```
|
||||
|
||||
This crate is `no_std` compatible. To use it without `std`:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
downcast-rs = { version = "1.2.0", default-features = false }
|
||||
```
|
||||
|
||||
To make a trait downcastable, make it extend either `downcast::Downcast` or
|
||||
`downcast::DowncastSync` and invoke `impl_downcast!` on it as in the examples
|
||||
below.
|
||||
|
||||
Since 1.1.0, the minimum supported Rust version is 1.33 to support `Rc` and `Arc`
|
||||
in the receiver position.
|
||||
|
||||
```rust
|
||||
trait Trait: Downcast {}
|
||||
impl_downcast!(Trait);
|
||||
|
||||
// Also supports downcasting `Arc`-ed trait objects by extending `DowncastSync`
|
||||
// and starting `impl_downcast!` with `sync`.
|
||||
trait TraitSync: DowncastSync {}
|
||||
impl_downcast!(sync TraitSync);
|
||||
|
||||
// With type parameters.
|
||||
trait TraitGeneric1<T>: Downcast {}
|
||||
impl_downcast!(TraitGeneric1<T>);
|
||||
|
||||
// With associated types.
|
||||
trait TraitGeneric2: Downcast { type G; type H; }
|
||||
impl_downcast!(TraitGeneric2 assoc G, H);
|
||||
|
||||
// With constraints on types.
|
||||
trait TraitGeneric3<T: Copy>: Downcast {
|
||||
type H: Clone;
|
||||
}
|
||||
impl_downcast!(TraitGeneric3<T> assoc H where T: Copy, H: Clone);
|
||||
|
||||
// With concrete types.
|
||||
trait TraitConcrete1<T: Copy>: Downcast {}
|
||||
impl_downcast!(concrete TraitConcrete1<u32>);
|
||||
|
||||
trait TraitConcrete2<T: Copy>: Downcast { type H; }
|
||||
impl_downcast!(concrete TraitConcrete2<u32> assoc H=f64);
|
||||
```
|
||||
|
||||
## Example without generics
|
||||
|
||||
```rust
|
||||
// Import macro via `macro_use` pre-1.30.
|
||||
#[macro_use]
|
||||
extern crate downcast_rs;
|
||||
use downcast_rs::DowncastSync;
|
||||
|
||||
// To create a trait with downcasting methods, extend `Downcast` or `DowncastSync`
|
||||
// and run `impl_downcast!()` on the trait.
|
||||
trait Base: DowncastSync {}
|
||||
impl_downcast!(sync Base); // `sync` => also produce `Arc` downcasts.
|
||||
|
||||
// Concrete types implementing Base.
|
||||
#[derive(Debug)]
|
||||
struct Foo(u32);
|
||||
impl Base for Foo {}
|
||||
#[derive(Debug)]
|
||||
struct Bar(f64);
|
||||
impl Base for Bar {}
|
||||
|
||||
fn main() {
|
||||
// Create a trait object.
|
||||
let mut base: Box<Base> = Box::new(Foo(42));
|
||||
|
||||
// Try sequential downcasts.
|
||||
if let Some(foo) = base.downcast_ref::<Foo>() {
|
||||
assert_eq!(foo.0, 42);
|
||||
} else if let Some(bar) = base.downcast_ref::<Bar>() {
|
||||
assert_eq!(bar.0, 42.0);
|
||||
}
|
||||
|
||||
assert!(base.is::<Foo>());
|
||||
|
||||
// Fail to convert `Box<Base>` into `Box<Bar>`.
|
||||
let res = base.downcast::<Bar>();
|
||||
assert!(res.is_err());
|
||||
let base = res.unwrap_err();
|
||||
// Convert `Box<Base>` into `Box<Foo>`.
|
||||
assert_eq!(42, base.downcast::<Foo>().map_err(|_| "Shouldn't happen.").unwrap().0);
|
||||
|
||||
// Also works with `Rc`.
|
||||
let mut rc: Rc<Base> = Rc::new(Foo(42));
|
||||
assert_eq!(42, rc.downcast_rc::<Foo>().map_err(|_| "Shouldn't happen.").unwrap().0);
|
||||
|
||||
// Since this trait is `Sync`, it also supports `Arc` downcasts.
|
||||
let mut arc: Arc<Base> = Arc::new(Foo(42));
|
||||
assert_eq!(42, arc.downcast_arc::<Foo>().map_err(|_| "Shouldn't happen.").unwrap().0);
|
||||
}
|
||||
```
|
||||
|
||||
## Example with a generic trait with associated types and constraints
|
||||
|
||||
```rust
|
||||
// Can call macro via namespace since rust 1.30.
|
||||
extern crate downcast_rs;
|
||||
use downcast_rs::Downcast;
|
||||
|
||||
// To create a trait with downcasting methods, extend `Downcast` or `DowncastSync`
|
||||
// and run `impl_downcast!()` on the trait.
|
||||
trait Base<T: Clone>: Downcast { type H: Copy; }
|
||||
downcast_rs::impl_downcast!(Base<T> assoc H where T: Clone, H: Copy);
|
||||
// or: impl_downcast!(concrete Base<u32> assoc H=f32)
|
||||
|
||||
// Concrete types implementing Base.
|
||||
struct Foo(u32);
|
||||
impl Base<u32> for Foo { type H = f32; }
|
||||
struct Bar(f64);
|
||||
impl Base<u32> for Bar { type H = f32; }
|
||||
|
||||
fn main() {
|
||||
// Create a trait object.
|
||||
let mut base: Box<Base<u32, H=f32>> = Box::new(Bar(42.0));
|
||||
|
||||
// Try sequential downcasts.
|
||||
if let Some(foo) = base.downcast_ref::<Foo>() {
|
||||
assert_eq!(foo.0, 42);
|
||||
} else if let Some(bar) = base.downcast_ref::<Bar>() {
|
||||
assert_eq!(bar.0, 42.0);
|
||||
}
|
||||
|
||||
assert!(base.is::<Bar>());
|
||||
}
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
Copyright 2020, Ashish Myles (maintainer) and contributors.
|
||||
This software is dual-licensed under the [MIT](LICENSE-MIT) and
|
||||
[Apache 2.0](LICENSE-APACHE) licenses.
|
||||
|
||||
### Contribution
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted
|
||||
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
|
||||
dual licensed as above, without any additional terms or conditions.
|
||||
Loading…
Add table
Add a link
Reference in a new issue