From 862453174dc15e5184a4f86bb14f203ccef94de6 Mon Sep 17 00:00:00 2001
From: HampusM <hampus@hampusmat.com>
Date: Tue, 19 Sep 2023 20:37:28 +0200
Subject: docs: add examples to DI container & related functions

---
 .../asynchronous/binding/scope_configurator.rs     | 91 +++++++++++++++++++++
 .../asynchronous/binding/when_configurator.rs      | 32 ++++++++
 src/di_container/asynchronous/mod.rs               | 92 ++++++++++++++++++++++
 .../blocking/binding/scope_configurator.rs         | 79 +++++++++++++++++++
 .../blocking/binding/when_configurator.rs          | 28 +++++++
 src/di_container/blocking/mod.rs                   | 80 +++++++++++++++++++
 6 files changed, 402 insertions(+)

(limited to 'src/di_container')

diff --git a/src/di_container/asynchronous/binding/scope_configurator.rs b/src/di_container/asynchronous/binding/scope_configurator.rs
index f079234..b63e644 100644
--- a/src/di_container/asynchronous/binding/scope_configurator.rs
+++ b/src/di_container/asynchronous/binding/scope_configurator.rs
@@ -47,6 +47,36 @@ where
     /// Configures the binding to be in a transient scope.
     ///
     /// This is the default.
+    ///
+    /// # Examples
+    /// ```
+    /// # use syrette::{AsyncDIContainer, injectable};
+    /// #
+    /// # struct Authenticator {}
+    /// #
+    /// # #[injectable(async = true)]
+    /// # impl Authenticator
+    /// # {
+    /// #     fn new() -> Self
+    /// #     {
+    /// #         Self {}
+    /// #     }
+    /// # }
+    /// #
+    /// # #[tokio::main]
+    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
+    /// let mut di_container = AsyncDIContainer::new();
+    ///
+    /// di_container
+    ///     .bind::<Authenticator>()
+    ///     .to::<Authenticator>()
+    ///     .await?
+    ///     .in_transient_scope()
+    ///     .await;
+    /// #
+    /// # Ok(())
+    /// # }
+    /// ```
     pub async fn in_transient_scope(
         self,
     ) -> AsyncBindingWhenConfigurator<'di_container, Interface>
@@ -60,6 +90,67 @@ where
     ///
     /// # Errors
     /// Will return Err if resolving the implementation fails.
+    ///
+    /// # Examples
+    /// ```
+    /// # use std::sync::atomic::{AtomicBool, Ordering};
+    /// # use syrette::{AsyncDIContainer, injectable};
+    /// #
+    /// # struct AudioManager
+    /// # {
+    /// #     is_sound_playing: AtomicBool
+    /// # }
+    /// #
+    /// # #[injectable(async = true)]
+    /// # impl AudioManager
+    /// # {
+    /// #     fn new() -> Self
+    /// #     {
+    /// #         Self { is_sound_playing: AtomicBool::new(false) }
+    /// #     }
+    /// #
+    /// #     fn play_long_sound(&self)
+    /// #     {
+    /// #         self.is_sound_playing.store(true, Ordering::Relaxed);
+    /// #     }
+    /// #
+    /// #     fn is_sound_playing(&self) -> bool
+    /// #     {
+    /// #        self.is_sound_playing.load(Ordering::Relaxed)
+    /// #     }
+    /// #
+    /// # }
+    /// #
+    /// # #[tokio::main]
+    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
+    /// let mut di_container = AsyncDIContainer::new();
+    ///
+    /// di_container
+    ///     .bind::<AudioManager>()
+    ///     .to::<AudioManager>()
+    ///     .await?
+    ///     .in_singleton_scope()
+    ///     .await;
+    ///
+    /// {
+    ///     let audio_manager = di_container
+    ///         .get::<AudioManager>()
+    ///         .await?
+    ///         .threadsafe_singleton()?;
+    ///
+    ///     audio_manager.play_long_sound();
+    /// }
+    ///
+    /// let audio_manager = di_container
+    ///     .get::<AudioManager>()
+    ///     .await?
+    ///     .threadsafe_singleton()?;
+    ///
+    /// assert!(audio_manager.is_sound_playing());
+    /// #
+    /// # Ok(())
+    /// # }
+    /// ```
     pub async fn in_singleton_scope(
         self,
     ) -> Result<
diff --git a/src/di_container/asynchronous/binding/when_configurator.rs b/src/di_container/asynchronous/binding/when_configurator.rs
index b7c2767..bc8e97f 100644
--- a/src/di_container/asynchronous/binding/when_configurator.rs
+++ b/src/di_container/asynchronous/binding/when_configurator.rs
@@ -34,6 +34,38 @@ where
     ///
     /// # Errors
     /// Will return Err if no binding for the interface already exists.
+    ///
+    /// # Examples
+    /// ```
+    /// # use syrette::{AsyncDIContainer, injectable};
+    /// #
+    /// # struct Kitten {}
+    /// #
+    /// # #[injectable(async = true)]
+    /// # impl Kitten
+    /// # {
+    /// #     fn new() -> Self
+    /// #     {
+    /// #         Self {}
+    /// #     }
+    /// # }
+    /// #
+    /// # #[tokio::main]
+    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
+    /// let mut di_container = AsyncDIContainer::new();
+    ///
+    /// di_container
+    ///     .bind::<Kitten>()
+    ///     .to::<Kitten>()
+    ///     .await?
+    ///     .in_transient_scope()
+    ///     .await
+    ///     .when_named("Billy")
+    ///     .await?;
+    /// #
+    /// # Ok(())
+    /// # }
+    /// ```
     pub async fn when_named(
         self,
         name: &'static str,
diff --git a/src/di_container/asynchronous/mod.rs b/src/di_container/asynchronous/mod.rs
index 4be232d..929e2c0 100644
--- a/src/di_container/asynchronous/mod.rs
+++ b/src/di_container/asynchronous/mod.rs
@@ -93,6 +93,31 @@ impl AsyncDIContainer
 impl AsyncDIContainer
 {
     /// Returns a new [`AsyncBindingBuilder`] for the given interface.
+    ///
+    /// # Examples
+    /// ```
+    /// # use syrette::{AsyncDIContainer, injectable};
+    /// #
+    /// # struct DiskWriter {}
+    /// #
+    /// # #[injectable(async = true)]
+    /// # impl DiskWriter
+    /// # {
+    /// #     fn new() -> Self
+    /// #     {
+    /// #         Self {}
+    /// #     }
+    /// # }
+    /// #
+    /// # #[tokio::main]
+    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
+    /// let mut di_container = AsyncDIContainer::new();
+    ///
+    /// di_container.bind::<DiskWriter>().to::<DiskWriter>().await?;
+    /// #
+    /// # Ok(())
+    /// # }
+    /// ```
     #[allow(clippy::missing_panics_doc)]
     pub fn bind<Interface>(&mut self) -> AsyncBindingBuilder<'_, Interface>
     where
@@ -112,6 +137,36 @@ impl AsyncDIContainer
     /// - No binding for `Interface` exists
     /// - Resolving the binding for `Interface` fails
     /// - Casting the binding for `Interface` fails
+    ///
+    /// # Examples
+    /// ```
+    /// # use syrette::{AsyncDIContainer, injectable};
+    /// #
+    /// # struct DeviceManager {}
+    /// #
+    /// # #[injectable(async = true)]
+    /// # impl DeviceManager
+    /// # {
+    /// #     fn new() -> Self
+    /// #     {
+    /// #         Self {}
+    /// #     }
+    /// # }
+    /// #
+    /// # #[tokio::main]
+    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
+    /// let mut di_container = AsyncDIContainer::new();
+    ///
+    /// di_container
+    ///     .bind::<DeviceManager>()
+    ///     .to::<DeviceManager>()
+    ///     .await?;
+    ///
+    /// let device_manager = di_container.get::<DeviceManager>().await?.transient();
+    /// #
+    /// # Ok(())
+    /// # }
+    /// ```
     pub async fn get<Interface>(
         &self,
     ) -> Result<SomePtr<Interface>, AsyncDIContainerError>
@@ -129,6 +184,43 @@ impl AsyncDIContainer
     /// - No binding for `Interface` with name `name` exists
     /// - Resolving the binding for `Interface` fails
     /// - Casting the binding for `Interface` fails
+    ///
+    /// # Examples
+    /// ```
+    /// # use syrette::{AsyncDIContainer, injectable};
+    /// #
+    /// # struct DeviceManager {}
+    /// #
+    /// # #[injectable(async = true)]
+    /// # impl DeviceManager
+    /// # {
+    /// #     fn new() -> Self
+    /// #     {
+    /// #         Self {}
+    /// #     }
+    /// # }
+    /// #
+    /// # #[tokio::main]
+    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
+    /// let mut di_container = AsyncDIContainer::new();
+    ///
+    /// di_container
+    ///     .bind::<DeviceManager>()
+    ///     .to::<DeviceManager>()
+    ///     .await?
+    ///     .in_transient_scope()
+    ///     .await
+    ///     .when_named("usb")
+    ///     .await;
+    ///
+    /// let device_manager = di_container
+    ///     .get_named::<DeviceManager>("usb")
+    ///     .await?
+    ///     .transient();
+    /// #
+    /// # Ok(())
+    /// # }
+    /// ```
     pub async fn get_named<Interface>(
         &self,
         name: &'static str,
diff --git a/src/di_container/blocking/binding/scope_configurator.rs b/src/di_container/blocking/binding/scope_configurator.rs
index 3d939ba..ee935a5 100644
--- a/src/di_container/blocking/binding/scope_configurator.rs
+++ b/src/di_container/blocking/binding/scope_configurator.rs
@@ -47,6 +47,33 @@ where
     /// Configures the binding to be in a transient scope.
     ///
     /// This is the default.
+    ///
+    /// # Examples
+    /// ```
+    /// # use syrette::{DIContainer, injectable};
+    /// #
+    /// # struct Authenticator {}
+    /// #
+    /// # #[injectable]
+    /// # impl Authenticator
+    /// # {
+    /// #     fn new() -> Self
+    /// #     {
+    /// #         Self {}
+    /// #     }
+    /// # }
+    /// #
+    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
+    /// let mut di_container = DIContainer::new();
+    ///
+    /// di_container
+    ///     .bind::<Authenticator>()
+    ///     .to::<Authenticator>()?
+    ///     .in_transient_scope();
+    /// #
+    /// # Ok(())
+    /// # }
+    /// ```
     #[allow(clippy::must_use_candidate)]
     pub fn in_transient_scope(self) -> BindingWhenConfigurator<'di_container, Interface>
     {
@@ -59,6 +86,58 @@ where
     ///
     /// # Errors
     /// Will return Err if resolving the implementation fails.
+    ///
+    /// # Examples
+    /// ```
+    /// # use std::sync::atomic::{AtomicBool, Ordering};
+    /// # use syrette::{DIContainer, injectable};
+    /// #
+    /// # struct AudioManager
+    /// # {
+    /// #     is_sound_playing: AtomicBool
+    /// # }
+    /// #
+    /// # #[injectable]
+    /// # impl AudioManager
+    /// # {
+    /// #     fn new() -> Self
+    /// #     {
+    /// #         Self { is_sound_playing: AtomicBool::new(false) }
+    /// #     }
+    /// #
+    /// #     fn play_long_sound(&self)
+    /// #     {
+    /// #         self.is_sound_playing.store(true, Ordering::Relaxed);
+    /// #     }
+    /// #
+    /// #     fn is_sound_playing(&self) -> bool
+    /// #     {
+    /// #        self.is_sound_playing.load(Ordering::Relaxed)
+    /// #     }
+    /// #
+    /// # }
+    /// #
+    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
+    /// let mut di_container = DIContainer::new();
+    ///
+    /// di_container
+    ///     .bind::<AudioManager>()
+    ///     .to::<AudioManager>()?
+    ///     .in_singleton_scope();
+    ///
+    /// {
+    ///     let audio_manager = di_container.get::<AudioManager>()?.singleton()?;
+    ///
+    ///     audio_manager.play_long_sound();
+    /// }
+    ///
+    /// let audio_manager = di_container.get::<AudioManager>()?.singleton()?;
+    ///
+    /// assert!(audio_manager.is_sound_playing());
+    /// #
+    /// # Ok(())
+    /// # }
+    /// ```
     pub fn in_singleton_scope(
         self,
     ) -> Result<
diff --git a/src/di_container/blocking/binding/when_configurator.rs b/src/di_container/blocking/binding/when_configurator.rs
index 2a1af2c..d23d213 100644
--- a/src/di_container/blocking/binding/when_configurator.rs
+++ b/src/di_container/blocking/binding/when_configurator.rs
@@ -34,6 +34,34 @@ where
     ///
     /// # Errors
     /// Will return Err if no binding for the interface already exists.
+    ///
+    /// # Examples
+    /// ```
+    /// # use syrette::{DIContainer, injectable};
+    /// #
+    /// # struct Kitten {}
+    /// #
+    /// # #[injectable]
+    /// # impl Kitten
+    /// # {
+    /// #     fn new() -> Self
+    /// #     {
+    /// #         Self {}
+    /// #     }
+    /// # }
+    /// #
+    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
+    /// let mut di_container = DIContainer::new();
+    ///
+    /// di_container
+    ///     .bind::<Kitten>()
+    ///     .to::<Kitten>()?
+    ///     .in_transient_scope()
+    ///     .when_named("Billy")?;
+    /// #
+    /// # Ok(())
+    /// # }
+    /// ```
     pub fn when_named(
         self,
         name: &'static str,
diff --git a/src/di_container/blocking/mod.rs b/src/di_container/blocking/mod.rs
index 69efe9a..df6e68c 100644
--- a/src/di_container/blocking/mod.rs
+++ b/src/di_container/blocking/mod.rs
@@ -95,6 +95,30 @@ impl DIContainer
 impl DIContainer
 {
     /// Returns a new [`BindingBuilder`] for the given interface.
+    ///
+    /// # Examples
+    /// ```
+    /// # use syrette::{DIContainer, injectable};
+    /// #
+    /// # struct DiskWriter {}
+    /// #
+    /// # #[injectable]
+    /// # impl DiskWriter
+    /// # {
+    /// #     fn new() -> Self
+    /// #     {
+    /// #         Self {}
+    /// #     }
+    /// # }
+    /// #
+    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
+    /// let mut di_container = DIContainer::new();
+    ///
+    /// di_container.bind::<DiskWriter>().to::<DiskWriter>()?;
+    /// #
+    /// # Ok(())
+    /// # }
+    /// ```
     #[allow(clippy::missing_panics_doc)]
     pub fn bind<Interface>(&mut self) -> BindingBuilder<'_, Interface>
     where
@@ -114,6 +138,32 @@ impl DIContainer
     /// - No binding for `Interface` exists
     /// - Resolving the binding for `Interface` fails
     /// - Casting the binding for `Interface` fails
+    ///
+    /// # Examples
+    /// ```
+    /// # use syrette::{DIContainer, injectable};
+    /// #
+    /// # struct DeviceManager {}
+    /// #
+    /// # #[injectable]
+    /// # impl DeviceManager
+    /// # {
+    /// #     fn new() -> Self
+    /// #     {
+    /// #         Self {}
+    /// #     }
+    /// # }
+    /// #
+    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
+    /// let mut di_container = DIContainer::new();
+    ///
+    /// di_container.bind::<DeviceManager>().to::<DeviceManager>()?;
+    ///
+    /// let device_manager = di_container.get::<DeviceManager>()?.transient();
+    /// #
+    /// # Ok(())
+    /// # }
+    /// ```
     pub fn get<Interface>(&self) -> Result<SomePtr<Interface>, DIContainerError>
     where
         Interface: 'static + ?Sized,
@@ -128,6 +178,36 @@ impl DIContainer
     /// - No binding for `Interface` with name `name` exists
     /// - Resolving the binding for `Interface` fails
     /// - Casting the binding for `Interface` fails
+    ///
+    /// # Examples
+    /// ```
+    /// # use syrette::{DIContainer, injectable};
+    /// #
+    /// # struct DeviceManager {}
+    /// #
+    /// # #[injectable]
+    /// # impl DeviceManager
+    /// # {
+    /// #     fn new() -> Self
+    /// #     {
+    /// #         Self {}
+    /// #     }
+    /// # }
+    /// #
+    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
+    /// let mut di_container = DIContainer::new();
+    ///
+    /// di_container
+    ///     .bind::<DeviceManager>()
+    ///     .to::<DeviceManager>()?
+    ///     .in_transient_scope()
+    ///     .when_named("usb")?;
+    ///
+    /// let device_manager = di_container.get_named::<DeviceManager>("usb")?.transient();
+    /// #
+    /// # Ok(())
+    /// # }
+    /// ```
     pub fn get_named<Interface>(
         &self,
         name: &'static str,
-- 
cgit v1.2.3-18-g5258