aboutsummaryrefslogtreecommitdiff
path: root/mingling_core/src/asset
diff options
context:
space:
mode:
Diffstat (limited to 'mingling_core/src/asset')
-rw-r--r--mingling_core/src/asset/chain/error.rs22
-rw-r--r--mingling_core/src/asset/core_invokes.rs31
-rw-r--r--mingling_core/src/asset/global_resource.rs39
-rw-r--r--mingling_core/src/asset/lazy_resource.rs34
-rw-r--r--mingling_core/src/asset/node.rs8
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 }
}
}