aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--macros/Cargo.toml2
-rw-r--r--macros/src/lib.rs76
-rw-r--r--src/di_container.rs91
-rw-r--r--src/errors/di_container.rs4
-rw-r--r--src/errors/injectable.rs3
-rw-r--r--src/errors/mod.rs2
-rw-r--r--src/interfaces/any_factory.rs3
-rw-r--r--src/interfaces/factory.rs11
-rw-r--r--src/interfaces/injectable.rs2
-rw-r--r--src/interfaces/mod.rs2
-rw-r--r--src/lib.rs1
-rw-r--r--src/ptr.rs5
12 files changed, 155 insertions, 47 deletions
diff --git a/macros/Cargo.toml b/macros/Cargo.toml
index d806396..d9392e6 100644
--- a/macros/Cargo.toml
+++ b/macros/Cargo.toml
@@ -17,3 +17,5 @@ quote = "1.0.18"
proc-macro2 = "1.0.40"
uuid = { version = "0.8", features = ["v4"] }
+[dev_dependencies]
+syrette = { version = "0.2.0", path = "..", features = ["factory"] }
diff --git a/macros/src/lib.rs b/macros/src/lib.rs
index 20eb7d3..aca4007 100644
--- a/macros/src/lib.rs
+++ b/macros/src/lib.rs
@@ -1,5 +1,8 @@
#![deny(clippy::all)]
#![deny(clippy::pedantic)]
+#![deny(missing_docs)]
+
+//! Macros for the [Syrette](https://crates.io/crates/syrette) crate.
use proc_macro::TokenStream;
use quote::quote;
@@ -27,8 +30,26 @@ use libs::intertrait_macros::gen_caster::generate_caster;
///
/// # Important
/// If the interface trait argument is excluded, you should either manually
-/// declare the interface with the `declare_interface` macro or use
-/// the `di_container_bind` macro to create a DI container binding.
+/// declare the interface with the [`declare_interface!`] macro or use
+/// the [`di_container_bind`] macro to create a DI container binding.
+///
+/// # Example
+/// ```
+/// use syrette::injectable;
+///
+/// struct PasswordManager {}
+///
+/// #[injectable]
+/// impl PasswordManager {
+/// pub fn new() -> Self {
+/// Self {}
+/// }
+/// }
+/// ```
+///
+/// [`DIContainer`]: ../syrette/di_container/struct.DIContainer.html
+/// [`Injectable`]: ../syrette/interfaces/injectable/trait.Injectable.html
+/// [`di_container_bind`]: ../syrette/macro.di_container_bind.html
#[proc_macro_attribute]
pub fn injectable(args_stream: TokenStream, impl_stream: TokenStream) -> TokenStream
{
@@ -62,6 +83,57 @@ pub fn injectable(args_stream: TokenStream, impl_stream: TokenStream) -> TokenSt
///
/// # Panics
/// If the attributed item is not a type alias.
+///
+/// # Examples
+/// ```
+/// use std::collections::HashMap;
+///
+/// use syrette::interfaces::factory::IFactory;
+/// use syrette::factory;
+///
+/// enum ConfigValue
+/// {
+/// String(String),
+/// Bool(bool),
+/// Int(i32),
+/// None,
+/// }
+///
+/// trait IConfigurator
+/// {
+/// fn configure(&self, key: String, value: ConfigValue);
+/// }
+///
+/// struct Configurator {
+/// config: HashMap<String, ConfigValue>,
+/// }
+///
+/// impl Configurator
+/// {
+/// fn new(keys: Vec<String>) -> Self
+/// {
+/// Self {
+/// config: HashMap::from(
+/// keys
+/// .iter()
+/// .map(|key| (key.clone(), ConfigValue::None))
+/// .collect::<HashMap<_, _>>()
+/// )
+/// }
+/// }
+/// }
+///
+/// impl IConfigurator for Configurator
+/// {
+/// fn configure(&self, key: String, value: ConfigValue)
+/// {
+/// // ...
+/// }
+/// }
+///
+/// #[factory]
+/// type IConfiguratorFactory = dyn IFactory<(Vec<String>,), dyn IConfigurator>;
+/// ```
#[proc_macro_attribute]
pub fn factory(_: TokenStream, type_alias_stream: TokenStream) -> TokenStream
{
diff --git a/src/di_container.rs b/src/di_container.rs
index e18fc3a..89bbcd1 100644
--- a/src/di_container.rs
+++ b/src/di_container.rs
@@ -1,3 +1,48 @@
+//! Dependency injection container and other related utilities.
+///
+/// # Examples
+/// ```
+/// use std::collections::HashMap;
+///
+/// use syrette::{DIContainer, injectable};
+/// use syrette::errors::di_container::DIContainerError;
+///
+/// trait IDatabaseService
+/// {
+/// fn get_all_records(&self, table_name: String) -> HashMap<String, String>;
+/// }
+///
+/// struct DatabaseService {}
+///
+/// #[injectable(IDatabaseService)]
+/// impl DatabaseService
+/// {
+/// fn new() -> Self
+/// {
+/// Self {}
+/// }
+/// }
+///
+/// impl IDatabaseService for DatabaseService
+/// {
+/// fn get_all_records(&self, table_name: String) -> HashMap<String, String>
+/// {
+/// // Do stuff here
+/// HashMap::<String, String>::new()
+/// }
+/// }
+///
+/// fn main() -> error_stack::Result<(), DIContainerError>
+/// {
+/// let mut di_container = DIContainer::new();
+///
+/// di_container.bind::<dyn IDatabaseService>().to::<DatabaseService>();
+///
+/// let database_service = di_container.get::<dyn IDatabaseService>()?;
+///
+/// Ok(())
+/// }
+/// ```
use std::any::type_name;
use std::marker::PhantomData;
@@ -101,50 +146,6 @@ where
}
/// Dependency injection container.
-///
-/// # Examples
-/// ```
-/// use std::collections::HashMap;
-///
-/// use syrette::{DIContainer, injectable};
-/// use syrette::errors::di_container::DIContainerError;
-///
-/// trait IDatabaseService
-/// {
-/// fn get_all_records(&self, table_name: String) -> HashMap<String, String>;
-/// }
-///
-/// struct DatabaseService {}
-///
-/// #[injectable(IDatabaseService)]
-/// impl DatabaseService
-/// {
-/// fn new() -> Self
-/// {
-/// Self {}
-/// }
-/// }
-///
-/// impl IDatabaseService for DatabaseService
-/// {
-/// fn get_all_records(&self, table_name: String) -> HashMap<String, String>
-/// {
-/// // Do stuff here
-/// HashMap::<String, String>::new()
-/// }
-/// }
-///
-/// fn main() -> error_stack::Result<(), DIContainerError>
-/// {
-/// let mut di_container = DIContainer::new();
-///
-/// di_container.bind::<dyn IDatabaseService>().to::<DatabaseService>();
-///
-/// let database_service = di_container.get::<dyn IDatabaseService>()?;
-///
-/// Ok(())
-/// }
-/// ```
pub struct DIContainer
{
bindings: DIContainerBindingMap,
@@ -176,7 +177,7 @@ impl DIContainer
/// - No binding for `Interface` exists
/// - Resolving the binding for `Interface` fails
/// - Casting the binding for `Interface` fails
- /// - The binding for `Interface` is not injectable
+ /// - The binding for `Interface` is not transient
pub fn get<Interface>(
&self,
) -> error_stack::Result<TransientPtr<Interface>, DIContainerError>
diff --git a/src/errors/di_container.rs b/src/errors/di_container.rs
index 3b8c717..127676f 100644
--- a/src/errors/di_container.rs
+++ b/src/errors/di_container.rs
@@ -1,8 +1,11 @@
+//! Error types for the DI container.
+
use std::fmt;
use std::fmt::{Display, Formatter};
use error_stack::Context;
+/// Error for when the DI container fails to do something.
#[derive(Debug)]
pub struct DIContainerError;
@@ -16,6 +19,7 @@ impl Display for DIContainerError
impl Context for DIContainerError {}
+/// Error for when the binding builder fails to do something.
#[derive(Debug)]
pub struct BindingBuilderError;
diff --git a/src/errors/injectable.rs b/src/errors/injectable.rs
index 6b0cdc5..63afa11 100644
--- a/src/errors/injectable.rs
+++ b/src/errors/injectable.rs
@@ -1,8 +1,11 @@
+//! Error types for structs implementing Injectable.
+
use core::fmt;
use std::fmt::{Display, Formatter};
use error_stack::Context;
+/// Error for when a injectable struct fails to be resolved.
#[derive(Debug)]
pub struct ResolveError;
diff --git a/src/errors/mod.rs b/src/errors/mod.rs
index b0d50f0..5f628d6 100644
--- a/src/errors/mod.rs
+++ b/src/errors/mod.rs
@@ -1,2 +1,4 @@
+//! Error types for various components of the library.
+
pub mod di_container;
pub mod injectable;
diff --git a/src/interfaces/any_factory.rs b/src/interfaces/any_factory.rs
index 41063e1..98ec144 100644
--- a/src/interfaces/any_factory.rs
+++ b/src/interfaces/any_factory.rs
@@ -1,3 +1,6 @@
+//! Interface for any factory to ever exist.
+
use crate::libs::intertrait::CastFrom;
+/// Interface for any factory to ever exist.
pub trait AnyFactory: CastFrom {}
diff --git a/src/interfaces/factory.rs b/src/interfaces/factory.rs
index 6f8e7c7..d3d55da 100644
--- a/src/interfaces/factory.rs
+++ b/src/interfaces/factory.rs
@@ -1,7 +1,18 @@
#![allow(clippy::module_name_repetitions)]
+
+//! Interface for a factory.
+
use crate::libs::intertrait::CastFrom;
use crate::ptr::TransientPtr;
+/// Interface for a factory.
+///
+/// # Examples
+/// ```
+/// use syrette::interface::factory::IFactory;
+///
+/// type StringFactory = dyn IFactory<(), String>;
+/// ```
pub trait IFactory<Args, ReturnInterface>:
Fn<Args, Output = TransientPtr<ReturnInterface>> + CastFrom
where
diff --git a/src/interfaces/injectable.rs b/src/interfaces/injectable.rs
index 0af1217..31cd21b 100644
--- a/src/interfaces/injectable.rs
+++ b/src/interfaces/injectable.rs
@@ -1,8 +1,10 @@
+//! Interface for structs that can be injected into or be injected to.
use crate::errors::injectable::ResolveError;
use crate::libs::intertrait::CastFrom;
use crate::ptr::TransientPtr;
use crate::DIContainer;
+/// Interface for structs that can be injected into or be injected to.
pub trait Injectable: CastFrom
{
/// Resolves the dependencies of the injectable.
diff --git a/src/interfaces/mod.rs b/src/interfaces/mod.rs
index 497521e..eef7190 100644
--- a/src/interfaces/mod.rs
+++ b/src/interfaces/mod.rs
@@ -1,3 +1,5 @@
+//! Various useful interfaces.
+
pub mod any_factory;
pub mod injectable;
diff --git a/src/lib.rs b/src/lib.rs
index d7314ad..4d1ce78 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,6 +1,7 @@
#![cfg_attr(feature = "factory", feature(unboxed_closures, fn_traits))]
#![deny(clippy::all)]
#![deny(clippy::pedantic)]
+#![deny(missing_docs)]
//! Syrette
//!
diff --git a/src/ptr.rs b/src/ptr.rs
index 00c74f4..082edf2 100644
--- a/src/ptr.rs
+++ b/src/ptr.rs
@@ -1,8 +1,13 @@
#![allow(clippy::module_name_repetitions)]
+
+//! Smart pointer type aliases.
use std::rc::Rc;
+/// A smart pointer unique to the holder.
pub type TransientPtr<Interface> = Box<Interface>;
+/// A smart pointer to a shared resource.
pub type SingletonPtr<Interface> = Rc<Interface>;
+/// A smart pointer to a factory.
pub type FactoryPtr<FactoryInterface> = Rc<FactoryInterface>;