aboutsummaryrefslogtreecommitdiff
path: root/src/libs/intertrait/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/intertrait/mod.rs')
-rw-r--r--src/libs/intertrait/mod.rs71
1 files changed, 32 insertions, 39 deletions
diff --git a/src/libs/intertrait/mod.rs b/src/libs/intertrait/mod.rs
index 1daca64..2cdc67d 100644
--- a/src/libs/intertrait/mod.rs
+++ b/src/libs/intertrait/mod.rs
@@ -12,64 +12,62 @@
* at your option.
*/
use std::any::{Any, TypeId};
-use std::collections::HashMap;
use std::rc::Rc;
-use std::sync::Arc;
+use ahash::AHashMap;
use linkme::distributed_slice;
use once_cell::sync::Lazy;
-mod hasher;
-
-use hasher::BuildFastHasher;
-
pub mod cast_box;
pub mod cast_rc;
pub type BoxedCaster = Box<dyn Any + Send + Sync>;
+type CasterFn = fn() -> (TypeId, BoxedCaster);
+
#[distributed_slice]
-pub static CASTERS: [fn() -> (TypeId, BoxedCaster)] = [..];
-
-static CASTER_MAP: Lazy<HashMap<(TypeId, TypeId), BoxedCaster, BuildFastHasher>> =
- Lazy::new(|| {
- CASTERS
- .iter()
- .map(|f| {
- let (type_id, caster) = f();
- ((type_id, (*caster).type_id()), caster)
- })
- .collect()
- });
-
-pub struct Caster<T: ?Sized + 'static>
+pub static CASTERS: [CasterFn] = [..];
+
+static CASTER_MAP: Lazy<AHashMap<(TypeId, TypeId), BoxedCaster>> = Lazy::new(|| {
+ CASTERS
+ .iter()
+ .map(|caster_fn| {
+ let (type_id, caster) = caster_fn();
+
+ ((type_id, (*caster).type_id()), caster)
+ })
+ .collect()
+});
+
+pub struct Caster<Trait: ?Sized + 'static>
{
/// Casts a `Box` holding a trait object for `Any` to another `Box` holding a trait object
- /// for trait `T`.
- pub cast_box: fn(from: Box<dyn Any>) -> Box<T>,
+ /// for `Trait`.
+ pub cast_box: fn(from: Box<dyn Any>) -> Box<Trait>,
/// Casts an `Rc` holding a trait object for `Any` to another `Rc` holding a trait object
- /// for trait `T`.
- pub cast_rc: fn(from: Rc<dyn Any>) -> Rc<T>,
+ /// for `Trait`.
+ pub cast_rc: fn(from: Rc<dyn Any>) -> Rc<Trait>,
}
-impl<T: ?Sized + 'static> Caster<T>
+impl<Trait: ?Sized + 'static> Caster<Trait>
{
pub fn new(
- cast_box: fn(from: Box<dyn Any>) -> Box<T>,
- cast_rc: fn(from: Rc<dyn Any>) -> Rc<T>,
- ) -> Caster<T>
+ cast_box: fn(from: Box<dyn Any>) -> Box<Trait>,
+ cast_rc: fn(from: Rc<dyn Any>) -> Rc<Trait>,
+ ) -> Caster<Trait>
{
- Caster::<T> { cast_box, cast_rc }
+ Caster::<Trait> { cast_box, cast_rc }
}
}
-/// Returns a `Caster<S, T>` from a concrete type `S` to a trait `T` implemented by it.
-fn caster<T: ?Sized + 'static>(type_id: TypeId) -> Option<&'static Caster<T>>
+/// Returns a `Caster<Implementation, Trait>` from a concrete type `Implementation`
+/// from inside `CASTER_MAP` to a `Trait` implemented by it.
+fn caster<Trait: ?Sized + 'static>(type_id: TypeId) -> Option<&'static Caster<Trait>>
{
CASTER_MAP
- .get(&(type_id, TypeId::of::<Caster<T>>()))
- .and_then(|caster| caster.downcast_ref::<Caster<T>>())
+ .get(&(type_id, TypeId::of::<Caster<Trait>>()))
+ .and_then(|caster| caster.downcast_ref::<Caster<Trait>>())
}
/// `CastFrom` must be extended by a trait that wants to allow for casting into another trait.
@@ -92,12 +90,7 @@ pub trait CastFrom: Any + 'static
fn rc_any(self: Rc<Self>) -> Rc<dyn Any>;
}
-pub trait CastFromSync: CastFrom + Sync + Send + 'static
-{
- fn arc_any(self: Arc<Self>) -> Arc<dyn Any + Sync + Send + 'static>;
-}
-
-impl<T: Sized + Any + 'static> CastFrom for T
+impl<Trait: Sized + Any + 'static> CastFrom for Trait
{
fn box_any(self: Box<Self>) -> Box<dyn Any>
{