diff options
Diffstat (limited to 'mingling_core/src/asset')
| -rw-r--r-- | mingling_core/src/asset/chain/error.rs | 22 | ||||
| -rw-r--r-- | mingling_core/src/asset/core_invokes.rs | 31 | ||||
| -rw-r--r-- | mingling_core/src/asset/global_resource.rs | 39 | ||||
| -rw-r--r-- | mingling_core/src/asset/lazy_resource.rs | 34 | ||||
| -rw-r--r-- | mingling_core/src/asset/node.rs | 8 |
5 files changed, 64 insertions, 70 deletions
diff --git a/mingling_core/src/asset/chain/error.rs b/mingling_core/src/asset/chain/error.rs index ad64195..bb5f679 100644 --- a/mingling_core/src/asset/chain/error.rs +++ b/mingling_core/src/asset/chain/error.rs @@ -13,8 +13,8 @@ pub enum ChainProcessError { impl std::fmt::Display for ChainProcessError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - ChainProcessError::Other(s) => write!(f, "Other error: {s}"), - ChainProcessError::IO(e) => write!(f, "IO error: {e}"), + Self::Other(s) => write!(f, "Other error: {s}"), + Self::IO(e) => write!(f, "IO error: {e}"), } } } @@ -22,15 +22,15 @@ impl std::fmt::Display for ChainProcessError { impl std::error::Error for ChainProcessError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { - ChainProcessError::IO(e) => Some(e), - ChainProcessError::Other(_) => None, + Self::IO(e) => Some(e), + Self::Other(_) => None, } } } impl From<std::io::Error> for ChainProcessError { fn from(e: std::io::Error) -> Self { - ChainProcessError::IO(e) + Self::IO(e) } } @@ -38,17 +38,15 @@ impl From<ProgramInternalExecuteError> for ChainProcessError { fn from(value: ProgramInternalExecuteError) -> Self { match value { ProgramInternalExecuteError::DispatcherNotFound => { - ChainProcessError::Other("DispatcherNotFound".into()) + Self::Other("DispatcherNotFound".into()) } ProgramInternalExecuteError::RendererNotFound(r) => { - ChainProcessError::Other(format!("RendererNotFound: {r}")) - } - ProgramInternalExecuteError::Other(e) => ChainProcessError::Other(e), - ProgramInternalExecuteError::IO(e) => { - ChainProcessError::Other(format!("IOError: {e:?}")) + Self::Other(format!("RendererNotFound: {r}")) } + ProgramInternalExecuteError::Other(e) => Self::Other(e), + ProgramInternalExecuteError::IO(e) => Self::Other(format!("IOError: {e:?}")), ProgramInternalExecuteError::REPLPanic(program_panic) => { - ChainProcessError::Other(format!("REPLPanic: {program_panic}")) + Self::Other(format!("REPLPanic: {program_panic}")) } } } diff --git a/mingling_core/src/asset/core_invokes.rs b/mingling_core/src/asset/core_invokes.rs index 6a3da2d..07e5092 100644 --- a/mingling_core/src/asset/core_invokes.rs +++ b/mingling_core/src/asset/core_invokes.rs @@ -48,18 +48,17 @@ where C: ProgramCollect<Enum = C> + 'static, T: Grouped<C>, { - if !self.create_by_res_injection { - panic!( - "The current RendererInvoker was not created by the resource injection system, so it cannot be executed!" - ); - } + assert!( + self.create_by_res_injection, + "The current RendererInvoker was not created by the resource injection system, so it cannot be executed!" + ); C::render(AnyOutput::new(value)) } } impl<T> ResourceMarker for RendererInvoker<T> { fn __resource_marker_clone(&self) -> Self { - RendererInvoker { + Self { phantom: PhantomData, create_by_res_injection: self.create_by_res_injection, } @@ -71,7 +70,7 @@ impl<T> ResourceMarker for RendererInvoker<T> { // Reason: RendererInvoker is designed to only be created through resource injection. // When the resource injection does not find a corresponding value, // this method will be used to generate a default value to pass in. - RendererInvoker { + Self { phantom: PhantomData, create_by_res_injection: true, } @@ -190,7 +189,7 @@ where } } - /// Continuously execute the chain until it is rendered into a RenderResult + /// Continuously execute the chain until it is rendered into a `RenderResult` /// /// This function can only be called when the `ChainInvoker` was created by the resource injection system /// (i.e., via `__resource_marker_default`). If the invoker was created manually or cloned outside @@ -198,7 +197,7 @@ where /// /// # Special Behavior /// - /// If an error occurs during rendering, or the result type does not contain a renderer, it will be rendered as an empty RenderResult + /// If an error occurs during rendering, or the result type does not contain a renderer, it will be rendered as an empty `RenderResult` /// /// # Panics /// @@ -229,19 +228,17 @@ where } } - #[inline(always)] fn pre_check(&self) { - if !self.create_by_res_injection { - panic!( - "The current ChainInvoker was not created by the resource injection system, so it cannot be executed!" - ); - } + assert!( + self.create_by_res_injection, + "The current ChainInvoker was not created by the resource injection system, so it cannot be executed!" + ); } } impl<T> ResourceMarker for ChainInvoker<T> { fn __resource_marker_clone(&self) -> Self { - ChainInvoker { + Self { phantom: PhantomData, create_by_res_injection: self.create_by_res_injection, } @@ -253,7 +250,7 @@ impl<T> ResourceMarker for ChainInvoker<T> { // Reason: ChainInvoker is designed to only be created through resource injection. // When the resource injection does not find a corresponding value, // this method will be used to generate a default value to pass in. - ChainInvoker { + Self { phantom: PhantomData, create_by_res_injection: true, } diff --git a/mingling_core/src/asset/global_resource.rs b/mingling_core/src/asset/global_resource.rs index 18e4446..f37edd0 100644 --- a/mingling_core/src/asset/global_resource.rs +++ b/mingling_core/src/asset/global_resource.rs @@ -6,7 +6,10 @@ use std::{ use crate::{ChainProcess, Program, ProgramCollect, this}; -pub(crate) type GlobalResources = Arc<Mutex<HashMap<TypeId, Box<dyn Any + Sync + Send>>>>; +/// A thread-safe, type-erased container for storing global resources keyed by their type. +/// +/// Use `Program::with_resource` to insert resources and `Program::res` to retrieve them. +pub type GlobalResources = Arc<Mutex<HashMap<TypeId, Box<dyn Any + Sync + Send>>>>; impl<C> Program<C> where @@ -87,17 +90,16 @@ where let Ok(mut guard) = self.resources.lock() else { return Res::__resource_marker_default(); }; - if let Some(arc_res) = guard + guard .get_mut(&TypeId::of::<Res>()) .and_then(|a| a.downcast_mut::<Arc<Res>>()) - { - match Arc::try_unwrap(std::mem::take(arc_res)) { - Ok(val) => val, - Err(arc) => (*arc).__resource_marker_clone(), - } - } else { - Res::__resource_marker_default() - } + .map_or_else( + Res::__resource_marker_default, + |arc_res| match Arc::try_unwrap(std::mem::take(arc_res)) { + Ok(val) => val, + Err(arc) => (*arc).__resource_marker_clone(), + }, + ) } /// Internal syntax for the `&mut MyResource` syntax of async #[chain], do not use directly. @@ -116,18 +118,23 @@ where let guard = self.resources.lock().ok()?; let boxed_any = guard.get(&TypeId::of::<Res>())?; let arc_res = boxed_any.as_ref().downcast_ref::<Arc<Res>>()?; - Some(GlobalResource::from(Arc::clone(arc_res))) + let result = GlobalResource::from(Arc::clone(arc_res)); + drop(guard); + Some(result) } - /// Get a resource by type, returning `GlobalResource<Res>` if present + /// Get a resource by type, returning `GlobalResource<Res>` if present. + /// + /// If the resource is not present, returns the provided [`ChainProcess`] as an `Err`. + /// + /// # Errors + /// + /// Returns `Err(route)` when the resource of type `Res` is not present in the store. pub fn res_or_route<Res: 'static + Send + Sync>( &self, route: ChainProcess<C>, ) -> Result<GlobalResource<Res>, ChainProcess<C>> { - match self.res() { - Some(r) => Ok(r), - None => Err(route), - } + self.res().map_or_else(|| Err(route), Ok) } /// Get a resource by type, returning `GlobalResource<Res>` or inserting a default diff --git a/mingling_core/src/asset/lazy_resource.rs b/mingling_core/src/asset/lazy_resource.rs index 3cb7563..f2a5e3d 100644 --- a/mingling_core/src/asset/lazy_resource.rs +++ b/mingling_core/src/asset/lazy_resource.rs @@ -54,12 +54,10 @@ impl<T: Send + Sync + 'static> LazyRes<T> { /// dropped. If the resource has not yet been initialized, the callback is stored /// and will be invoked once initialization happens *and* the `LazyRes` is later /// dropped. + #[must_use] pub fn with_on_drop(mut self, on_drop: impl FnOnce(T) + Send + Sync + 'static) -> Self { match &mut self.inner { - LazyInner::Uninit(_, existing_opt) => { - *existing_opt = Some(Box::new(on_drop)); - } - LazyInner::Init(_, existing_opt) => { + LazyInner::Uninit(_, existing_opt) | LazyInner::Init(_, existing_opt) => { *existing_opt = Some(Box::new(on_drop)); } } @@ -72,17 +70,14 @@ impl<T: Send + Sync + 'static> LazyRes<T> { /// upon initialization. pub fn set_on_drop(&mut self, on_drop: impl FnOnce(T) + Send + Sync + 'static) { match &mut self.inner { - LazyInner::Uninit(_, existing_opt) => { - *existing_opt = Some(Box::new(on_drop)); - } - LazyInner::Init(_, existing_opt) => { + LazyInner::Uninit(_, existing_opt) | LazyInner::Init(_, existing_opt) => { *existing_opt = Some(Box::new(on_drop)); } } } /// Returns `true` if the resource has been initialized. - pub fn is_initialized(&self) -> bool { + pub const fn is_initialized(&self) -> bool { matches!(&self.inner, LazyInner::Init(_, _)) } @@ -157,6 +152,10 @@ impl<T: Send + Sync + 'static> LazyRes<T> { /// /// If the resource has not been initialized, the initializer is called first. /// This is different from `into_inner()` which returns `None` if uninitialized. + /// + /// # Panics + /// + /// Panics if the resource has not been initialized. pub fn unwrap(mut self) -> T { match std::mem::replace( &mut self.inner, @@ -216,10 +215,7 @@ impl<T: Send + Sync + 'static> Drop for LazyRes<T> { } } -impl<T: Send + Sync + 'static> Default for LazyRes<T> -where - T: Default, -{ +impl<T: Send + Sync + Default + 'static> Default for LazyRes<T> { /// Creates an uninitialized `LazyRes<T>` whose initializer returns `T::default()`. fn default() -> Self { Self::new(|| T::default()) @@ -237,6 +233,7 @@ impl<T: Send + Sync + 'static> From<T> for LazyRes<T> { impl<T: Send + Sync + 'static> LazyRes<T> { /// Creates a lazily initialized resource using `T::default()` as the initializer. + #[must_use] pub fn lazy_default() -> Self where T: Default, @@ -256,6 +253,7 @@ impl<T: Send + Sync + 'static> LazyRes<T> { /// create a corresponding `LazyRes<T>`. pub trait LazyInit: Send + Sync + 'static { /// Creates a lazily initialized resource for this type using `Default` as the initializer. + #[must_use] fn lazy_default() -> LazyRes<Self> where Self: Default, @@ -274,10 +272,7 @@ pub trait LazyInit: Send + Sync + 'static { impl<T: Send + Sync + 'static> LazyInit for T {} -impl<T: Send + Sync + 'static> ResourceMarker for LazyRes<T> -where - T: Default + Clone, -{ +impl<T: Send + Sync + 'static + Default + Clone> ResourceMarker for LazyRes<T> { /// Clones the lazy resource. The cloned resource retains any initialized value, /// but the initializer is reset to `T::default()`. fn __resource_marker_clone(&self) -> Self { @@ -290,10 +285,7 @@ where } /// Returns a default lazy resource (uninitialized, using `T::default()` as the initializer). - fn __resource_marker_default() -> Self - where - T: Default, - { + fn __resource_marker_default() -> Self { Self::default() } diff --git a/mingling_core/src/asset/node.rs b/mingling_core/src/asset/node.rs index caf34ec..b9002b6 100644 --- a/mingling_core/src/asset/node.rs +++ b/mingling_core/src/asset/node.rs @@ -12,24 +12,24 @@ pub struct Node { impl Node { /// Append a new part to the node path. #[must_use] - pub fn join(self, node: impl Into<String>) -> Node { + pub fn join(self, node: impl Into<String>) -> Self { let mut new_node = self.node; new_node.push(node.into()); - Node { node: new_node } + Self { node: new_node } } } impl From<&str> for Node { fn from(s: &str) -> Self { let node = s.split('.').map(|part| kebab_case!(part)).collect(); - Node { node } + Self { node } } } impl From<String> for Node { fn from(s: String) -> Self { let node = s.split('.').map(|part| kebab_case!(part)).collect(); - Node { node } + Self { node } } } |
