From 607d8d50b76665b67ca6f3124aa81773bec110b7 Mon Sep 17 00:00:00 2001 From: HampusM Date: Mon, 25 Dec 2023 22:53:13 +0100 Subject: WIP Linkme dependency removal --- src/private/cast/arc.rs | 93 ---------------- src/private/cast/boxed.rs | 87 --------------- src/private/cast/error.rs | 20 ---- src/private/cast/mod.rs | 273 ---------------------------------------------- src/private/cast/rc.rs | 87 --------------- src/private/mod.rs | 6 - 6 files changed, 566 deletions(-) delete mode 100644 src/private/cast/arc.rs delete mode 100644 src/private/cast/boxed.rs delete mode 100644 src/private/cast/error.rs delete mode 100644 src/private/cast/mod.rs delete mode 100644 src/private/cast/rc.rs delete mode 100644 src/private/mod.rs (limited to 'src/private') diff --git a/src/private/cast/arc.rs b/src/private/cast/arc.rs deleted file mode 100644 index 1fbdf8b..0000000 --- a/src/private/cast/arc.rs +++ /dev/null @@ -1,93 +0,0 @@ -//! Originally from Intertrait by CodeChain -//! -//! -//! -//! -//! Licensed under either of -//! -//! Apache License, Version 2.0 (LICENSE-APACHE or ) -//! MIT license (LICENSE-MIT or ) -//! -//! at your option. -use std::any::type_name; -use std::sync::Arc; - -use crate::private::cast::error::CastError; -use crate::private::cast::{get_caster, CastFromArc}; - -pub trait CastArc -{ - /// Casts an `Arc` with `Self` into an `Arc` with `Dest`. - fn cast(self: Arc) -> Result, CastError>; -} - -/// A blanket implementation of `CastArc` for traits extending `CastFrom`, `Sync`, and -/// `Send`. -impl CastArc for CastFromSelf -{ - fn cast(self: Arc) -> Result, CastError> - { - let caster = - get_caster::((*self).type_id()).map_err(CastError::GetCasterFailed)?; - - let cast_arc = caster - .opt_cast_arc - .ok_or(CastError::NotArcCastable(type_name::()))?; - - cast_arc(self.arc_any()).map_err(|err| CastError::CastFailed { - source: err, - from: type_name::(), - to: type_name::(), - }) - } -} - -#[cfg(test)] -mod tests -{ - use std::any::Any; - use std::fmt::{Debug, Display}; - use std::sync::Arc; - - use super::*; - use crate::test_utils::subjects; - - #[test] - fn can_cast_arc() - { - let concrete_ninja = Arc::new(subjects::Ninja); - - let abstract_ninja: Arc = concrete_ninja; - - let debug_ninja_result = abstract_ninja.cast::(); - - assert!(debug_ninja_result.is_ok()); - } - - #[test] - fn cannot_cast_arc_wrong() - { - let concrete_ninja = Arc::new(subjects::Ninja); - - let abstract_ninja: Arc = concrete_ninja; - - let display_ninja_result = abstract_ninja.cast::(); - - assert!(matches!( - display_ninja_result, - Err(CastError::GetCasterFailed(_)) - )); - } - - #[test] - fn can_cast_arc_from_any() - { - let concrete_ninja = Arc::new(subjects::Ninja); - - let any_ninja: Arc = concrete_ninja; - - let debug_ninja_result = any_ninja.cast::(); - - assert!(debug_ninja_result.is_ok()); - } -} diff --git a/src/private/cast/boxed.rs b/src/private/cast/boxed.rs deleted file mode 100644 index 074346c..0000000 --- a/src/private/cast/boxed.rs +++ /dev/null @@ -1,87 +0,0 @@ -//! Originally from Intertrait by CodeChain -//! -//! -//! -//! -//! Licensed under either of -//! -//! Apache License, Version 2.0 (LICENSE-APACHE or ) -//! MIT license (LICENSE-MIT or ) -//! -//! at your option. - -use std::any::type_name; - -use crate::private::cast::error::CastError; -use crate::private::cast::{get_caster, CastFrom}; - -pub trait CastBox -{ - /// Casts a `Box` with `Self` into a `Box` with `Dest`. - fn cast(self: Box) -> Result, CastError>; -} - -/// A blanket implementation of `CastBox` for traits extending `CastFrom`. -impl CastBox for CastFromSelf -{ - fn cast(self: Box) -> Result, CastError> - { - let caster = - get_caster::((*self).type_id()).map_err(CastError::GetCasterFailed)?; - - (caster.cast_box)(self.box_any()).map_err(|err| CastError::CastFailed { - source: err, - from: type_name::(), - to: type_name::(), - }) - } -} - -#[cfg(test)] -mod tests -{ - use std::any::Any; - use std::fmt::{Debug, Display}; - - use super::*; - use crate::test_utils::subjects; - - #[test] - fn can_cast_box() - { - let concrete_ninja = Box::new(subjects::Ninja); - - let abstract_ninja: Box = concrete_ninja; - - let debug_ninja_result = abstract_ninja.cast::(); - - assert!(debug_ninja_result.is_ok()); - } - - #[test] - fn cannot_cast_box_wrong() - { - let concrete_ninja = Box::new(subjects::Ninja); - - let abstract_ninja: Box = concrete_ninja; - - let display_ninja_result = abstract_ninja.cast::(); - - assert!(matches!( - display_ninja_result, - Err(CastError::GetCasterFailed(_)) - )); - } - - #[test] - fn can_cast_box_from_any() - { - let concrete_ninja = Box::new(subjects::Ninja); - - let any_ninja: Box = concrete_ninja; - - let debug_ninja_result = any_ninja.cast::(); - - assert!(debug_ninja_result.is_ok()); - } -} diff --git a/src/private/cast/error.rs b/src/private/cast/error.rs deleted file mode 100644 index c6ed01d..0000000 --- a/src/private/cast/error.rs +++ /dev/null @@ -1,20 +0,0 @@ -use crate::private::cast::{CasterError, GetCasterError}; - -#[derive(thiserror::Error, Debug)] -pub enum CastError -{ - #[error("Failed to get caster")] - GetCasterFailed(#[from] GetCasterError), - - #[error("Failed to cast from {from} to {to}")] - CastFailed - { - #[source] - source: CasterError, - from: &'static str, - to: &'static str, - }, - - #[error("'{0}' can't be cast to an Arc")] - NotArcCastable(&'static str), -} diff --git a/src/private/cast/mod.rs b/src/private/cast/mod.rs deleted file mode 100644 index ddff2a4..0000000 --- a/src/private/cast/mod.rs +++ /dev/null @@ -1,273 +0,0 @@ -//! Originally from Intertrait by CodeChain -//! -//! -//! -//! -//! Licensed under either of -//! -//! Apache License, Version 2.0 (LICENSE-APACHE or ) -//! MIT license (LICENSE-MIT or ) -//! -//! at your option. -use std::any::{Any, TypeId}; -use std::rc::Rc; -use std::sync::Arc; - -use ahash::AHashMap; -use linkme::distributed_slice; -use once_cell::sync::Lazy; - -pub mod arc; -pub mod boxed; -pub mod error; -pub mod rc; - -pub type BoxedCaster = Box; - -/// A distributed slice gathering constructor functions for [`Caster`]s. -/// -/// A constructor function returns `TypeId` of a concrete type involved in the casting -/// and a `Box` of a type or trait backed by a [`Caster`]. -#[distributed_slice] -pub static CASTERS: [fn() -> (TypeId, BoxedCaster)] = [..]; - -/// A `HashMap` mapping `TypeId` of a [`Caster`] to an instance of it. -static CASTER_MAP: Lazy> = Lazy::new(|| { - CASTERS - .iter() - .map(|caster_fn| { - let (type_id, caster) = caster_fn(); - - ((type_id, (*caster).type_id()), caster) - }) - .collect() -}); - -type CastBoxFn = fn(from: Box) -> Result, CasterError>; - -type CastRcFn = fn(from: Rc) -> Result, CasterError>; - -type CastArcFn = - fn(from: Arc) -> Result, CasterError>; - -/// A `Caster` knows how to cast a type or trait to the type or trait `Dest`. Each -/// `Caster` instance is specific to a concrete type. That is, it knows how to cast to -/// single specific type or trait implemented by single specific type. -pub struct Caster -{ - /// Casts a `Box` holding a type or trait object for `Any` to another `Box` holding a - /// type or trait `Dest`. - pub cast_box: CastBoxFn, - - /// Casts an `Rc` holding a type or trait for `Any` to another `Rc` holding a type or - /// trait `Dest`. - pub cast_rc: CastRcFn, - - /// Casts an `Arc` holding a type or trait for `Any + Sync + Send + 'static` to - /// another `Arc` holding a type or trait for `Dest`. - pub opt_cast_arc: Option>, -} - -impl Caster -{ - pub fn new(cast_box: CastBoxFn, cast_rc: CastRcFn) -> Caster - { - Caster:: { - cast_box, - cast_rc, - opt_cast_arc: None, - } - } - - #[allow(clippy::similar_names)] - pub fn new_sync( - cast_box: CastBoxFn, - cast_rc: CastRcFn, - cast_arc: CastArcFn, - ) -> Caster - { - Caster:: { - cast_box, - cast_rc, - opt_cast_arc: Some(cast_arc), - } - } -} - -#[derive(Debug, thiserror::Error)] -pub enum CasterError -{ - #[error("Failed to cast Box")] - CastBoxFailed, - - #[error("Failed to cast Rc")] - CastRcFailed, - - #[error("Failed to cast Arc")] - CastArcFailed, -} - -/// Returns a `Caster` from a concrete type with the id `type_id` to a type or trait -/// `Dest`. -fn get_caster( - type_id: TypeId, -) -> Result<&'static Caster, GetCasterError> -{ - let any_caster = CASTER_MAP - .get(&(type_id, TypeId::of::>())) - .ok_or(GetCasterError::NotFound)?; - - any_caster - .downcast_ref::>() - .ok_or(GetCasterError::DowncastFailed) -} - -#[derive(Debug, thiserror::Error)] -pub enum GetCasterError -{ - #[error("Caster not found")] - NotFound, - - #[error("Failed to downcast caster")] - DowncastFailed, -} - -/// `CastFrom` must be extended by a trait that wants to allow for casting into another -/// trait. -/// -/// It is used for obtaining a trait object for [`Any`] from a trait object for its -/// sub-trait, and blanket implemented for all `Sized + Any + 'static` types. -/// -/// # Examples -/// ```ignore -/// trait Source: CastFrom { -/// ... -/// } -/// ``` -pub trait CastFrom: Any + 'static -{ - /// Returns a `Box` of `Any`, which is backed by the type implementing this trait. - fn box_any(self: Box) -> Box; - - /// Returns an `Rc` of `Any`, which is backed by the type implementing this trait. - fn rc_any(self: Rc) -> Rc; -} - -/// This trait must be extended by a trait that is `Any + Sync + Send + 'static` -/// and wants to allow for casting into another trait behind references and smart pointers -/// especially including `Arc`. -/// -/// It is used for obtaining a trait object for [`Any + Sync + Send + 'static`] from an -/// object for its sub-trait, and blanket implemented for all `Sized + Sync + Send + -/// 'static` types. -/// -/// # Examples -/// ```ignore -/// trait Source: CastFromArc { -/// ... -/// } -/// ``` -pub trait CastFromArc: CastFrom + Sync + Send + 'static -{ - fn arc_any(self: Arc) -> Arc; -} - -impl CastFrom for Source -{ - fn box_any(self: Box) -> Box - { - self - } - - fn rc_any(self: Rc) -> Rc - { - self - } -} - -impl CastFrom for dyn Any + 'static -{ - fn box_any(self: Box) -> Box - { - self - } - - fn rc_any(self: Rc) -> Rc - { - self - } -} - -impl CastFromArc for Source -{ - fn arc_any(self: Arc) -> Arc - { - self - } -} - -impl CastFrom for dyn Any + Sync + Send + 'static -{ - fn box_any(self: Box) -> Box - { - self - } - - fn rc_any(self: Rc) -> Rc - { - self - } -} - -impl CastFromArc for dyn Any + Sync + Send + 'static -{ - fn arc_any(self: Arc) -> Arc - { - self - } -} - -#[cfg(test)] -mod tests -{ - use std::any::TypeId; - use std::fmt::Debug; - - use linkme::distributed_slice; - - use super::*; - use crate::test_utils::subjects; - - #[distributed_slice(super::CASTERS)] - static TEST_CASTER: fn() -> (TypeId, BoxedCaster) = create_test_caster; - - fn create_test_caster() -> (TypeId, BoxedCaster) - { - let type_id = TypeId::of::(); - - let caster = Box::new(Caster:: { - cast_box: |from| { - let concrete = from - .downcast::() - .map_err(|_| CasterError::CastBoxFailed)?; - - Ok(concrete as Box) - }, - cast_rc: |from| { - let concrete = from - .downcast::() - .map_err(|_| CasterError::CastRcFailed)?; - - Ok(concrete as Rc) - }, - opt_cast_arc: Some(|from| { - let concrete = from - .downcast::() - .map_err(|_| CasterError::CastArcFailed)?; - - Ok(concrete as Arc) - }), - }); - (type_id, caster) - } -} diff --git a/src/private/cast/rc.rs b/src/private/cast/rc.rs deleted file mode 100644 index 11d137a..0000000 --- a/src/private/cast/rc.rs +++ /dev/null @@ -1,87 +0,0 @@ -//! Originally from Intertrait by CodeChain -//! -//! -//! -//! -//! Licensed under either of -//! -//! Apache License, Version 2.0 (LICENSE-APACHE or ) -//! MIT license (LICENSE-MIT or ) -//! -//! at your option. -use std::any::type_name; -use std::rc::Rc; - -use crate::private::cast::error::CastError; -use crate::private::cast::{get_caster, CastFrom}; - -pub trait CastRc -{ - /// Casts an `Rc` with `Self `into a `Rc` with `Dest`. - fn cast(self: Rc) -> Result, CastError>; -} - -/// A blanket implementation of `CastRc` for traits extending `CastFrom`. -impl CastRc for CastFromSelf -{ - fn cast(self: Rc) -> Result, CastError> - { - let caster = - get_caster::((*self).type_id()).map_err(CastError::GetCasterFailed)?; - - (caster.cast_rc)(self.rc_any()).map_err(|err| CastError::CastFailed { - source: err, - from: type_name::(), - to: type_name::(), - }) - } -} - -#[cfg(test)] -mod tests -{ - use std::any::Any; - use std::fmt::{Debug, Display}; - - use super::*; - use crate::test_utils::subjects; - - #[test] - fn can_cast_rc() - { - let concrete_ninja = Rc::new(subjects::Ninja); - - let abstract_ninja: Rc = concrete_ninja; - - let debug_ninja_result = abstract_ninja.cast::(); - - assert!(debug_ninja_result.is_ok()); - } - - #[test] - fn cannot_cast_rc_wrong() - { - let concrete_ninja = Rc::new(subjects::Ninja); - - let abstract_ninja: Rc = concrete_ninja; - - let display_ninja_result = abstract_ninja.cast::(); - - assert!(matches!( - display_ninja_result, - Err(CastError::GetCasterFailed(_)) - )); - } - - #[test] - fn can_cast_rc_from_any() - { - let concrete_ninja = Rc::new(subjects::Ninja); - - let any_ninja: Rc = concrete_ninja; - - let debug_ninja_result = any_ninja.cast::(); - - assert!(debug_ninja_result.is_ok()); - } -} diff --git a/src/private/mod.rs b/src/private/mod.rs deleted file mode 100644 index 9b03ce8..0000000 --- a/src/private/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -//! This module contains items that's not in the public API but is used by the -//! library user with the expansions of the macros in the syrette_macros crate. - -pub mod cast; - -pub extern crate linkme; -- cgit v1.2.3-18-g5258