Trait otter::imports::DynCastExt
source · [−]pub trait DynCastExt {
fn dyn_cast<T>(self) -> Result<Self::Target, Self::Source>
where
Self: DynCastExtHelper<T>,
T: ?Sized;
fn dyn_upcast<T>(self) -> Self::Target
where
Self: DynCastExtAdvHelper<T, T, Source = Self::Target>,
T: ?Sized;
fn dyn_cast_adv<F, T>(self) -> Result<Self::Target, Self::Source>
where
Self: DynCastExtAdvHelper<F, T>,
F: ?Sized,
T: ?Sized;
fn dyn_cast_with_config<C>(self) -> Result<Self::Target, Self::Source>
where
C: DynCastConfig,
Self: DynCastExtAdvHelper<<C as DynCastConfig>::Source, <C as DynCastConfig>::Target>;
}
Expand description
Simplifies the use of the DynCast
trait by abstracting away the difference
between different ways of storing trait objects.
Required Methods
Use this to cast from one trait object type to another.
The T
type parameter should be the target trait, not the target type.
Examples
use cast_trait_object::{create_dyn_cast_config, impl_dyn_cast, DynCast, DynCastExt};
create_dyn_cast_config!(SuperToSubCast = Super => Sub);
trait Super: DynCast<SuperToSubCast> {}
trait Sub: Super {}
struct Foo;
impl Super for Foo {}
impl Sub for Foo {}
impl_dyn_cast!(Foo as Super => Sub);
let foo: &dyn Super = &Foo;
// Casting to a sub trait is fallible (the error allows us to keep using the
// `dyn Super` trait object if we want which can be important if we are casting
// movable types like `Box<dyn Trait>`):
let foo: &dyn Sub = foo.dyn_cast().ok().unwrap();
fn dyn_upcast<T>(self) -> Self::Target where
Self: DynCastExtAdvHelper<T, T, Source = Self::Target>,
T: ?Sized,
fn dyn_upcast<T>(self) -> Self::Target where
Self: DynCastExtAdvHelper<T, T, Source = Self::Target>,
T: ?Sized,
Use this to upcast a trait to one of its supertraits.
The T
type parameter should be the wanted supertrait.
This works by using a cast where both the source and target is the wanted trait.
Examples
use cast_trait_object::{create_dyn_cast_config, impl_dyn_cast, DynCast, DynCastExt};
create_dyn_cast_config!(SuperUpcast = Super => Super);
trait Super: DynCast<SuperUpcast> {}
trait Sub: Super {}
struct Foo;
impl Super for Foo {}
impl Sub for Foo {}
impl_dyn_cast!(Foo as Super => Super);
let foo: &dyn Sub = &Foo;
// Upcasting to a supertrait is infallible (so we don't need any error handling):
let foo /*: &dyn Super*/ = foo.dyn_upcast::<dyn Super>();
fn dyn_cast_adv<F, T>(self) -> Result<Self::Target, Self::Source> where
Self: DynCastExtAdvHelper<F, T>,
F: ?Sized,
T: ?Sized,
fn dyn_cast_adv<F, T>(self) -> Result<Self::Target, Self::Source> where
Self: DynCastExtAdvHelper<F, T>,
F: ?Sized,
T: ?Sized,
Use this to cast from one trait object type to another. This method is more
customizable than the dyn_cast
method. Here you can also specify the
“source” trait from which the cast is defined. This can for example allow
using casts from a supertrait of the current trait object.
The F
Type parameter should be the trait that is returned if the cast
fails.
The T
type parameter should be the target trait, not the target type.
Examples
use cast_trait_object::{create_dyn_cast_config, impl_dyn_cast, DynCast, DynCastExt};
create_dyn_cast_config!(SuperToSub1Cast = Super => Sub1);
create_dyn_cast_config!(SuperToSub2Cast = Super => Sub2);
trait Super: DynCast<SuperToSub1Cast> + DynCast<SuperToSub2Cast> {}
trait Sub1: Super {}
trait Sub2: Super {}
struct Foo;
impl Super for Foo {}
impl Sub1 for Foo {}
impl Sub2 for Foo {}
impl_dyn_cast!(Foo as Super => Sub1, Sub2);
let foo: &dyn Sub1 = &Foo;
let foo /*: &dyn Sub2 */ = foo.dyn_cast_adv::<dyn Super, dyn Sub2>().ok().unwrap();
In the above example we need to use dyn_cast_adv
instead of dyn_cast
since we don’t want to use our
current trait object as the source of the cast, we want to use one of our super
traits. The code foo.dyn_cast::<dyn Sub2>()
would be the same as
foo.dyn_cast_adv::<dyn Sub1, dyn Sub2>()
and would fail to compile.
fn dyn_cast_with_config<C>(self) -> Result<Self::Target, Self::Source> where
C: DynCastConfig,
Self: DynCastExtAdvHelper<<C as DynCastConfig>::Source, <C as DynCastConfig>::Target>,
fn dyn_cast_with_config<C>(self) -> Result<Self::Target, Self::Source> where
C: DynCastConfig,
Self: DynCastExtAdvHelper<<C as DynCastConfig>::Source, <C as DynCastConfig>::Target>,
Use this to cast from one trait object type to another. With this method the type parameter is a config type that uniquely specifies which cast should be preformed.
The C
type parameter should be the config type that is used to preform
the cast.
This method can do the same things as the dyn_cast_adv
method but allows specifying the source and target traits via a “config”
type instead of using trait names.
Examples
use cast_trait_object::{create_dyn_cast_config, impl_dyn_cast, DynCast, DynCastExt};
create_dyn_cast_config!(SuperToSub1Cast = Super => Sub1);
create_dyn_cast_config!(SuperToSub2Cast = Super => Sub2);
trait Super: DynCast<SuperToSub1Cast> + DynCast<SuperToSub2Cast> {}
trait Sub1: Super {}
trait Sub2: Super {}
struct Foo;
impl Super for Foo {}
impl Sub1 for Foo {}
impl Sub2 for Foo {}
impl_dyn_cast!(Foo as Super => Sub1, Sub2);
let foo: &dyn Sub1 = &Foo;
let foo /*: &dyn Sub2 */ = foo.dyn_cast_with_config::<SuperToSub2Cast>().ok().unwrap();