//! Smart pointer type aliases. use std::rc::Rc; use std::sync::Arc; use paste::paste; use crate::errors::ptr::{SomePtrError, SomeThreadsafePtrError}; /// A smart pointer for a interface in the transient scope. pub type TransientPtr = Box; /// A smart pointer to a interface in the singleton scope. pub type SingletonPtr = Rc; /// A threadsafe smart pointer to a interface in the singleton scope. pub type ThreadsafeSingletonPtr = Arc; /// A smart pointer to a factory. #[cfg(feature = "factory")] #[cfg_attr(doc_cfg, doc(cfg(feature = "factory")))] pub type FactoryPtr = Rc; /// A threadsafe smart pointer to a factory. #[cfg(feature = "factory")] #[cfg_attr(doc_cfg, doc(cfg(feature = "factory")))] pub type ThreadsafeFactoryPtr = Arc; macro_rules! create_as_variant_fn { ($enum: ident, $variant: ident) => { create_as_variant_fn!($enum, $variant,); }; ($enum: ident, $variant: ident, $($attrs: meta),*) => { paste! { #[doc = "Returns as the `" [<$variant>] "` variant.\n" "\n" "# Errors\n" "Will return Err if it's not the `" [<$variant>] "` variant." ] $(#[$attrs])* pub fn [<$variant:snake>](self) -> Result<[<$variant Ptr>], [<$enum Error>]> { if let $enum::$variant(ptr) = self { return Ok(ptr); } Err([<$enum Error>]::WrongPtrType { expected: stringify!($variant), found: self.into() }) } } }; } /// Some smart pointer. #[derive(strum_macros::IntoStaticStr)] pub enum SomePtr where Interface: 'static + ?Sized, { /// A smart pointer to a interface in the transient scope. Transient(TransientPtr), /// A smart pointer to a interface in the singleton scope. Singleton(SingletonPtr), /// A smart pointer to a factory. #[cfg(feature = "factory")] #[cfg_attr(doc_cfg, doc(cfg(feature = "factory")))] Factory(FactoryPtr), } impl SomePtr where Interface: 'static + ?Sized, { create_as_variant_fn!(SomePtr, Transient); create_as_variant_fn!(SomePtr, Singleton); create_as_variant_fn!( SomePtr, Factory, cfg(feature = "factory"), cfg_attr(doc_cfg, doc(cfg(feature = "factory"))) ); } /// Some threadsafe smart pointer. #[derive(strum_macros::IntoStaticStr)] pub enum SomeThreadsafePtr where Interface: 'static + ?Sized, { /// A smart pointer to a interface in the transient scope. Transient(TransientPtr), /// A smart pointer to a interface in the singleton scope. ThreadsafeSingleton(ThreadsafeSingletonPtr), /// A smart pointer to a factory. #[cfg(feature = "factory")] #[cfg_attr(doc_cfg, doc(cfg(feature = "factory")))] ThreadsafeFactory(ThreadsafeFactoryPtr), } impl SomeThreadsafePtr where Interface: 'static + ?Sized, { create_as_variant_fn!(SomeThreadsafePtr, Transient); create_as_variant_fn!(SomeThreadsafePtr, ThreadsafeSingleton); create_as_variant_fn!( SomeThreadsafePtr, ThreadsafeFactory, cfg(feature = "factory"), cfg_attr(doc_cfg, doc(cfg(feature = "factory"))) ); }