async_injector/
lib.rs

1//! [<img alt="github" src="https://img.shields.io/badge/github-udoprog/async--injector-8da0cb?style=for-the-badge&logo=github" height="20">](https://github.com/udoprog/async-injector)
2//! [<img alt="crates.io" src="https://img.shields.io/crates/v/async-injector.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/async-injector)
3//! [<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-async--injector-66c2a5?style=for-the-badge&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K" height="20">](https://docs.rs/async-injector)
4//!
5//! Asynchronous dependency injection for Rust.
6//!
7//! This library provides the glue which allows for building robust decoupled
8//! applications that can be reconfigured dynamically while they are running.
9//!
10//! For a real world example of how this is used, see [`OxidizeBot`] for which
11//! it was written.
12//!
13//! <br>
14//!
15//! ## Usage
16//!
17//! Add `async-injector` to your `Cargo.toml`.
18//!
19//! ```toml
20//! [dependencies]
21//! async-injector = "0.19.4"
22//! ```
23//!
24//! <br>
25//!
26//! ## Example
27//!
28//! In the following we'll showcase the injection of a *fake* `Database`. The
29//! idea here would be that if something about the database connection changes,
30//! a new instance of `Database` would be created and cause the application to
31//! reconfigure itself.
32//!
33//! ```rust
34//! use async_injector::{Key, Injector, Provider};
35//!
36//! #[derive(Debug, Clone)]
37//! struct Database;
38//!
39//! #[derive(Debug, Provider)]
40//! struct Service {
41//!     #[dependency]
42//!     database: Database,
43//! }
44//!
45//! async fn service(injector: Injector) -> Result<(), Box<dyn std::error::Error>> {
46//!     let mut provider = Service::provider(&injector).await?;
47//!
48//!     let Service { database } = provider.wait().await;
49//!     println!("Service got initial database {database:?}!");
50//!
51//!     let Service { database } = provider.wait().await;
52//!     println!("Service got new database {database:?}!");
53//!
54//!     Ok(())
55//! }
56//! ```
57//!
58//! > **Note:** This is available as the `database` example:
59//! > ```sh
60//! > cargo run --example database
61//! > ```
62//!
63//! The [`Injector`] above provides a structured broadcasting system that allows
64//! for configuration updates to be cleanly integrated into asynchronous
65//! contexts. The update itself is triggered by some other component that is
66//! responsible for constructing the `Database` instance.
67//!
68//! Building up the components of your application like this means that it can
69//! be reconfigured without restarting it. Providing a much richer user
70//! experience.
71//!
72//! <br>
73//!
74//! ## Injecting multiple things of the same type
75//!
76//! In the previous section you might've noticed that the injected value was
77//! solely discriminated by its type: `Database`. In this example we'll show how
78//! [`Key`] can be used to *tag* values of the same type with different names to
79//! discriminate them. This can be useful when dealing with overly generic types
80//! like [`String`].
81//!
82//! The tag used must be serializable with [`serde`]. It must also not use any
83//! components which [cannot be hashed], like `f32` and `f64`.
84//!
85//! <br>
86//!
87//! ### A simple greeter
88//!
89//! The following example showcases the use of `Key` to injector two different
90//! values into an asynchronous `greeter`.
91//!
92//! ```rust,no_run
93//! use async_injector::{Key, Injector};
94//!
95//! async fn greeter(injector: Injector) -> Result<(), Box<dyn std::error::Error>> {
96//!     let name = Key::<String>::tagged("name")?;
97//!     let fun = Key::<String>::tagged("fun")?;
98//!
99//!     let (mut name_stream, mut name) = injector.stream_key(name).await;
100//!     let (mut fun_stream, mut fun) = injector.stream_key(fun).await;
101//!
102//!     loop {
103//!         tokio::select! {
104//!             update = name_stream.recv() => {
105//!                 name = update;
106//!             }
107//!             update = fun_stream.recv() => {
108//!                 fun = update;
109//!             }
110//!         }
111//!
112//!         let (Some(name), Some(fun)) = (&name, &fun) else {
113//!             continue;
114//!         };
115//!
116//!         println!("Hi {name}! I see you do \"{fun}\" for fun!");
117//!         return Ok(());
118//!     }
119//! }
120//! ```
121//!
122//! > **Note:** you can run this using:
123//! > ```sh
124//! > cargo run --example greeter
125//! > ```
126//!
127//! The loop above can be implemented more easily using the [`Provider`] derive,
128//! so let's do that.
129//!
130//! ```rust,no_run
131//! use async_injector::{Injector, Provider};
132//!
133//! #[derive(Provider)]
134//! struct Dependencies {
135//!     #[dependency(tag = "name")]
136//!     name: String,
137//!     #[dependency(tag = "fun")]
138//!     fun: String,
139//! }
140//!
141//! async fn greeter(injector: Injector) -> Result<(), Box<dyn std::error::Error>> {
142//!     let mut provider = Dependencies::provider(&injector).await?;
143//!     let Dependencies { name, fun } = provider.wait().await;
144//!     println!("Hi {name}! I see you do \"{fun}\" for fun!");
145//!     Ok(())
146//! }
147//! ```
148//!
149//! > **Note:** you can run this using:
150//! > ```sh
151//! > cargo run --example greeter_provider
152//! > ```
153//!
154//! <br>
155//!
156//! ## The `Provider` derive
157//!
158//! The [`Provider`] derive can be used to conveniently implement the mechanism
159//! necessary to wait for a specific set of dependencies to become available.
160//!
161//! It builds a companion structure next to the type being provided called
162//! `<name>Provider` which in turn implements the following set of methods:
163//!
164//! ```rust,no_run
165//! use async_injector::{Error, Injector};
166//!
167//! # struct Dependencies {}
168//! impl Dependencies {
169//!     /// Construct a new provider.
170//!     async fn provider(injector: &Injector) -> Result<DependenciesProvider, Error>
171//!     # { todo!() }
172//! }
173//!
174//! struct DependenciesProvider {
175//!     /* private fields */
176//! }
177//!
178//! impl DependenciesProvider {
179//!     /// Try to construct the current value. Returns [None] unless all
180//!     /// required dependencies are available.
181//!     fn build(&mut self) -> Option<Dependencies>
182//!     # { todo!() }
183//!
184//!     /// Wait until we can successfully build the complete provided
185//!     /// value.
186//!     async fn wait(&mut self) -> Dependencies
187//!     # { todo!() }
188//!
189//!     /// Wait until the provided value has changed. Either some
190//!     /// dependencies are no longer available at which it returns `None`,
191//!     /// or all dependencies are available after which we return the
192//!     /// build value.
193//!     async fn wait_for_update(&mut self) -> Option<Dependencies>
194//!     # { todo!() }
195//! }
196//! ```
197//!
198//! <br>
199//!
200//! ### Fixed arguments to `Provider`
201//!
202//! Any arguments which do not have the `#[dependency]` attribute are known as
203//! "fixed" arguments. These must be passed in when calling the `provider`
204//! constructor. They can also be used during tag construction.
205//!
206//! ```rust,no_run
207//! use async_injector::{Injector, Key, Provider};
208//!
209//! #[derive(Provider)]
210//! struct Dependencies {
211//!     name_tag: &'static str,
212//!     #[dependency(tag = name_tag)]
213//!     name: String,
214//! }
215//!
216//! async fn greeter(injector: Injector) -> Result<(), Box<dyn std::error::Error>> {
217//!     let mut provider = Dependencies::provider(&injector, "name").await?;
218//!     let Dependencies { name, .. } = provider.wait().await;
219//!     println!("Hi {name}!");
220//!     Ok(())
221//! }
222//! ```
223//!
224//! [`OxidizeBot`]: https://github.com/udoprog/OxidizeBot
225//! [cannot be hashed]: https://internals.rust-lang.org/t/f32-f64-should-implement-hash/5436
226//! [`Injector`]: https://docs.rs/async-injector/0/async_injector/struct.Injector.html
227//! [`Key`]: https://docs.rs/async-injector/0/async_injector/struct.Key.html
228//! [`Provider`]: https://docs.rs/async-injector/0/async_injector/derive.Provider.html
229//! [`serde`]: https://serde.rs
230//! [`Stream`]: https://docs.rs/futures-core/0/futures_core/stream/trait.Stream.html
231//! [`String`]: https://doc.rust-lang.org/std/string/struct.String.html
232
233#![deny(missing_docs)]
234
235use hashbrown::HashMap;
236use serde_hashkey as hashkey;
237use std::any::{Any, TypeId};
238use std::cmp;
239use std::error;
240use std::fmt;
241use std::hash;
242use std::marker;
243use std::mem;
244use std::ptr;
245use std::sync::Arc;
246use tokio::sync::{broadcast, RwLock};
247
248/// The read guard produced by [Ref::read].
249pub type RefReadGuard<'a, T> = tokio::sync::RwLockReadGuard<'a, T>;
250
251/// re-exports for the Provider derive.
252#[doc(hidden)]
253pub mod derive {
254    pub use tokio::select;
255}
256
257/// Helper derive to implement a "provider".
258///
259/// The `Provider` derive can only be used on structs. Each field designates a
260/// value that must either be injected, or provided during construction.
261///
262/// ```rust
263/// use async_injector::Provider;
264/// use serde::Serialize;
265///
266/// #[derive(Serialize)]
267/// enum Tag {
268///     Table,
269///     Url,
270/// }
271///
272/// #[derive(Provider)]
273/// struct Deps {
274///     fixed: String,
275///     #[dependency(optional, tag = Tag::Table)]
276///     table: Option<String>,
277///     #[dependency(tag = Tag::Url)]
278///     url: String,
279///     #[dependency]
280///     connection_limit: u32,
281/// }
282/// ```
283///
284/// This generates another struct named `DepsProvider`, with the following api:
285///
286/// ```rust,no_run
287/// use async_injector::{Error, Injector};
288///
289/// # struct Deps {}
290/// impl Deps {
291///     /// Construct a new provider.
292///     async fn provider(injector: &Injector, fixed: String) -> Result<DepsProvider, Error>
293///     # { todo!() }
294/// }
295///
296/// struct DepsProvider {
297///     /* private fields */
298/// }
299///
300/// impl DepsProvider {
301///     /// Try to construct the current value. Returns [None] unless all
302///     /// required dependencies are available.
303///     fn build(&mut self) -> Option<Deps>
304///     # { todo!() }
305///
306///     /// Wait until we can successfully build the complete provided
307///     /// value.
308///     async fn wait(&mut self) -> Deps
309///     # { todo!() }
310///
311///     /// Wait until the provided value has changed. Either some
312///     /// dependencies are no longer available at which it returns `None`,
313///     /// or all dependencies are available after which we return the
314///     /// build value.
315///     async fn wait_for_update(&mut self) -> Option<Deps>
316///     # { todo!() }
317/// }
318/// ```
319///
320/// The `provider` associated function takes the reference to an injector as its
321/// first argument and any fields which are not marked as a `#[dependency]`.
322/// These are called fixed fields.
323///
324/// <br>
325///
326/// # The `#[dependency]` field attribute
327///
328/// The `#[dependency]` attribute can be used to mark fields which need to be
329/// injected. It takes an optional `#[dependency(tag = ...)]`, which allows you
330/// to specify the tag to use when constructing the injected [Key].
331///
332/// ```rust
333/// use async_injector::Provider;
334/// use serde::Serialize;
335///
336/// #[derive(Serialize)]
337/// enum Tag {
338///     First,
339/// }
340///
341/// #[derive(Provider)]
342/// struct Params {
343///     #[dependency(tag = Tag::First)]
344///     tagged: String,
345///     #[dependency]
346///     number: u32,
347/// }
348/// ```
349///
350/// Optional fields use the [Option] type and must be marked with the `optional`
351/// meta attribute.
352///
353/// ```rust
354/// use async_injector::Provider;
355///
356/// #[derive(Provider)]
357/// struct Params {
358///     #[dependency(optional)]
359///     table: Option<String>,
360/// }
361/// ```
362///
363/// [Key]: https://docs.rs/async-injector/0/async_injector/struct.Key.html
364#[doc(inline)]
365pub use async_injector_derive::Provider;
366
367/// Errors that can be raised by various functions in the [`Injector`].
368#[derive(Debug)]
369pub enum Error {
370    /// Error when serializing key.
371    SerializationError(hashkey::Error),
372}
373
374impl fmt::Display for Error {
375    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
376        match *self {
377            Self::SerializationError(..) => "serialization error".fmt(fmt),
378        }
379    }
380}
381
382impl error::Error for Error {
383    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
384        match self {
385            Self::SerializationError(e) => Some(e),
386        }
387    }
388}
389
390impl From<hashkey::Error> for Error {
391    fn from(value: hashkey::Error) -> Self {
392        Error::SerializationError(value)
393    }
394}
395
396/// A stream of updates to a value in the [`Injector`].
397///
398/// This is created using [Injector::stream] or [Injector::stream_key] and can
399/// be used to make sure that an asynchronous process has access to the most
400/// up-to-date value from the injector.
401pub struct Stream<T> {
402    rx: broadcast::Receiver<Option<Value>>,
403    marker: marker::PhantomData<T>,
404}
405
406impl<T> Stream<T> {
407    /// Receive the next injected element from the stream.
408    pub async fn recv(&mut self) -> Option<T> {
409        let value = loop {
410            let value = self.rx.recv().await;
411
412            match value {
413                Ok(value) => break value,
414                Err(broadcast::error::RecvError::Lagged { .. }) => continue,
415                _ => return None,
416            };
417        };
418
419        let value = match value {
420            Some(value) => value,
421            _ => return None,
422        };
423
424        // Safety: The expected type parameter is encoded and maintained in the
425        // Stream<T> type.
426        Some(unsafe { value.downcast::<T>() })
427    }
428}
429
430/// An opaque value holder, similar to Any, but can be cloned and relies
431/// entirely on external type information.
432struct Value {
433    data: *const (),
434    // clone function, to use when cloning the value.
435    value_clone_fn: unsafe fn(*const ()) -> *const (),
436    // drop function, to use when dropping the value.
437    value_drop_fn: unsafe fn(*const ()),
438}
439
440impl Value {
441    /// Construct a new opaque value.
442    pub(crate) fn new<T>(data: T) -> Self
443    where
444        T: 'static + Clone + Send + Sync,
445    {
446        return Self {
447            data: Box::into_raw(Box::new(data)) as *const (),
448            value_clone_fn: value_clone_fn::<T>,
449            value_drop_fn: value_drop_fn::<T>,
450        };
451
452        /// Clone implementation for a given value.
453        unsafe fn value_clone_fn<T>(data: *const ()) -> *const ()
454        where
455            T: Clone,
456        {
457            let data = T::clone(&*(data as *const _));
458            Box::into_raw(Box::new(data)) as *const ()
459        }
460
461        /// Drop implementation for a given value.
462        unsafe fn value_drop_fn<T>(value: *const ()) {
463            ptr::drop_in_place(value as *mut () as *mut T)
464        }
465    }
466
467    /// Downcast the given value reference.
468    ///
469    /// # Safety
470    ///
471    /// Assumes that we know the type of the underlying value.
472    pub(crate) unsafe fn downcast_ref<T>(&self) -> &T {
473        &*(self.data as *const T)
474    }
475
476    /// Downcast the given value to a mutable reference.
477    ///
478    /// # Safety
479    ///
480    /// Assumes that we know the type of the underlying value.
481    pub(crate) unsafe fn downcast_mut<T>(&mut self) -> &mut T {
482        &mut *(self.data as *const T as *mut T)
483    }
484
485    /// Downcast the given value.
486    ///
487    /// # Safety
488    ///
489    /// Assumes that we know the correct, underlying type of the value.
490    pub(crate) unsafe fn downcast<T>(self) -> T {
491        let value = Box::from_raw(self.data as *const T as *mut T);
492        mem::forget(self);
493        *value
494    }
495}
496
497/// Safety: Send + Sync bound is enforced in all constructors of `Value`.
498unsafe impl Send for Value {}
499unsafe impl Sync for Value {}
500
501impl Clone for Value {
502    fn clone(&self) -> Self {
503        let data = unsafe { (self.value_clone_fn)(self.data as *const _) };
504
505        Self {
506            data,
507            value_clone_fn: self.value_clone_fn,
508            value_drop_fn: self.value_drop_fn,
509        }
510    }
511}
512
513impl Drop for Value {
514    fn drop(&mut self) {
515        unsafe {
516            (self.value_drop_fn)(self.data);
517        }
518    }
519}
520
521struct Storage {
522    value: Arc<RwLock<Option<Value>>>,
523    tx: broadcast::Sender<Option<Value>>,
524}
525
526impl Default for Storage {
527    fn default() -> Self {
528        let (tx, _) = broadcast::channel(1);
529        Self {
530            value: Arc::new(RwLock::new(None)),
531            tx,
532        }
533    }
534}
535
536struct Inner {
537    storage: RwLock<HashMap<RawKey, Storage>>,
538}
539
540/// An injector of dependencies.
541///
542/// Injectors are defined in hierarchies where an injector is either the root
543/// injector as created using [Injector::new].
544#[derive(Clone)]
545pub struct Injector {
546    inner: Arc<Inner>,
547}
548
549impl Injector {
550    /// Construct and use an [`Injector`].
551    ///
552    /// # Example
553    ///
554    /// ```
555    /// use async_injector::Injector;
556    ///
557    /// # #[tokio::main] async fn main() {
558    /// let injector = Injector::new();
559    ///
560    /// assert_eq!(None, injector.get::<u32>().await);
561    /// injector.update(1u32).await;
562    /// assert_eq!(Some(1u32), injector.get::<u32>().await);
563    /// assert!(injector.clear::<u32>().await.is_some());
564    /// assert_eq!(None, injector.get::<u32>().await);
565    /// # }
566    /// ```
567    ///
568    /// Example using a [`Stream`].
569    ///
570    /// ```
571    /// use async_injector::Injector;
572    ///
573    /// #[derive(Clone)]
574    /// struct Database;
575    ///
576    /// # #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> {
577    /// let injector = Injector::new();
578    ///
579    /// let database = injector.var::<Database>().await;
580    ///
581    /// assert!(database.read().await.is_none());
582    /// injector.update(Database).await;
583    /// assert!(database.read().await.is_some());
584    /// # Ok(()) }
585    /// ```
586    pub fn new() -> Self {
587        Self::default()
588    }
589
590    /// Get a value from the injector.
591    ///
592    /// This will cause the clear to be propagated to all streams set up using
593    /// [`stream`]. And for future calls to [`get`] to return the updated value.
594    ///
595    /// [`stream`]: Injector::stream
596    /// [`get`]: Injector::get
597    ///
598    /// # Examples
599    ///
600    /// ```
601    /// use async_injector::Injector;
602    ///
603    /// # #[tokio::main] async fn main() {
604    /// let injector = Injector::new();
605    ///
606    /// assert_eq!(None, injector.get::<u32>().await);
607    /// injector.update(1u32).await;
608    /// assert_eq!(Some(1u32), injector.get::<u32>().await);
609    /// assert!(injector.clear::<u32>().await.is_some());
610    /// assert_eq!(None, injector.get::<u32>().await);
611    /// # }
612    /// ```
613    pub async fn clear<T>(&self) -> Option<T>
614    where
615        T: Clone + Any + Send + Sync,
616    {
617        self.clear_key(Key::<T>::of()).await
618    }
619
620    /// Clear the given value with the given key.
621    ///
622    /// This will cause the clear to be propagated to all streams set up using
623    /// [`stream`]. And for future calls to [`get`] to return the updated value.
624    ///
625    /// [`stream`]: Injector::stream
626    /// [`get`]: Injector::get
627    ///
628    /// # Examples
629    ///
630    /// ```
631    /// use async_injector::{Key, Injector};
632    ///
633    /// # #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> {
634    /// let injector = Injector::new();
635    /// let k = Key::<u32>::tagged("first")?;
636    ///
637    /// assert_eq!(None, injector.get_key(&k).await);
638    /// injector.update_key(&k, 1u32).await;
639    /// assert_eq!(Some(1u32), injector.get_key(&k).await);
640    /// assert!(injector.clear_key(&k).await.is_some());
641    /// assert_eq!(None, injector.get_key(&k).await);
642    /// # Ok(()) }
643    /// ```
644    pub async fn clear_key<T>(&self, key: impl AsRef<Key<T>>) -> Option<T>
645    where
646        T: Clone + Any + Send + Sync,
647    {
648        let key = key.as_ref().as_raw_key();
649
650        let storage = self.inner.storage.read().await;
651        let storage = storage.get(key)?;
652        let value = storage.value.write().await.take()?;
653        let _ = storage.tx.send(None);
654        Some(unsafe { value.downcast() })
655    }
656
657    /// Set the given value and notify any subscribers.
658    ///
659    /// This will cause the update to be propagated to all streams set up using
660    /// [`stream`]. And for future calls to [`get`] to return the updated value.
661    ///
662    /// [`stream`]: Injector::stream
663    /// [`get`]: Injector::get
664    ///
665    /// # Examples
666    ///
667    /// ```
668    /// use async_injector::Injector;
669    ///
670    /// # #[tokio::main]
671    /// # async fn main() {
672    /// let injector = Injector::new();
673    ///
674    /// assert_eq!(None, injector.get::<u32>().await);
675    /// injector.update(1u32).await;
676    /// assert_eq!(Some(1u32), injector.get::<u32>().await);
677    /// # }
678    /// ```
679    pub async fn update<T>(&self, value: T) -> Option<T>
680    where
681        T: Clone + Any + Send + Sync,
682    {
683        self.update_key(Key::<T>::of(), value).await
684    }
685
686    /// Update the value associated with the given key.
687    ///
688    /// This will cause the update to be propagated to all streams set up using
689    /// [`stream`]. And for future calls to [`get`] to return the updated value.
690    ///
691    /// [`stream`]: Injector::stream
692    /// [`get`]: Injector::get
693    ///
694    /// # Examples
695    ///
696    /// ```
697    /// use async_injector::{Key, Injector};
698    ///
699    /// # #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> {
700    /// let injector = Injector::new();
701    /// let k = Key::<u32>::tagged("first")?;
702    ///
703    /// assert_eq!(None, injector.get_key(&k).await);
704    /// injector.update_key(&k, 1u32).await;
705    /// assert_eq!(Some(1u32), injector.get_key(&k).await);
706    /// # Ok(()) }
707    /// ```
708    pub async fn update_key<T>(&self, key: impl AsRef<Key<T>>, value: T) -> Option<T>
709    where
710        T: Clone + Any + Send + Sync,
711    {
712        let key = key.as_ref().as_raw_key();
713        let value = Value::new(value);
714
715        let mut storage = self.inner.storage.write().await;
716        let storage = storage.entry(key.clone()).or_default();
717        let _ = storage.tx.send(Some(value.clone()));
718        let old = storage.value.write().await.replace(value)?;
719        Some(unsafe { old.downcast() })
720    }
721
722    /// Test if a given value exists by type.
723    ///
724    /// # Examples
725    ///
726    /// ```
727    /// use async_injector::{Key, Injector};
728    ///
729    /// # #[tokio::main] async fn main() {
730    /// let injector = Injector::new();
731    ///
732    /// assert_eq!(false, injector.exists::<u32>().await);
733    /// injector.update(1u32).await;
734    /// assert_eq!(true, injector.exists::<u32>().await);
735    /// # }
736    /// ```
737    pub async fn exists<T>(&self) -> bool
738    where
739        T: Clone + Any + Send + Sync,
740    {
741        self.exists_key(Key::<T>::of()).await
742    }
743
744    /// Test if a given value exists by key.
745    ///
746    /// # Examples
747    ///
748    /// ```
749    /// use async_injector::{Key, Injector};
750    ///
751    /// # #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> {
752    /// let injector = Injector::new();
753    /// let k = Key::<u32>::tagged("first")?;
754    ///
755    /// assert_eq!(false, injector.exists_key(&k).await);
756    /// injector.update_key(&k, 1u32).await;
757    /// assert_eq!(true, injector.exists_key(&k).await);
758    /// # Ok(()) }
759    /// ```
760    pub async fn exists_key<T>(&self, key: impl AsRef<Key<T>>) -> bool
761    where
762        T: Clone + Any + Send + Sync,
763    {
764        let key = key.as_ref().as_raw_key();
765        let storage = self.inner.storage.read().await;
766
767        if let Some(s) = storage.get(key) {
768            s.value.read().await.is_some()
769        } else {
770            false
771        }
772    }
773
774    /// Mutate the given value by type.
775    ///
776    /// # Examples
777    ///
778    /// ```
779    /// use async_injector::Injector;
780    ///
781    /// # #[tokio::main] async fn main() {
782    /// let injector = Injector::new();
783    ///
784    /// injector.update(1u32).await;
785    ///
786    /// let old = injector.mutate(|value: &mut u32| {
787    ///     let old = *value;
788    ///     *value += 1;
789    ///     old
790    /// }).await;
791    ///
792    /// assert_eq!(Some(1u32), old);
793    /// # }
794    /// ```
795    pub async fn mutate<T, M, R>(&self, mutator: M) -> Option<R>
796    where
797        T: Clone + Any + Send + Sync,
798        M: FnMut(&mut T) -> R,
799    {
800        self.mutate_key(Key::<T>::of(), mutator).await
801    }
802
803    /// Mutate the given value by key.
804    ///
805    /// # Examples
806    ///
807    /// ```
808    /// use async_injector::{Key, Injector};
809    ///
810    /// # #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> {
811    /// let injector = Injector::new();
812    /// let k = Key::<u32>::tagged("first")?;
813    ///
814    /// injector.update_key(&k, 1u32).await;
815    ///
816    /// let old = injector.mutate_key(&k, |value| {
817    ///     let old = *value;
818    ///     *value += 1;
819    ///     old
820    /// }).await;
821    ///
822    /// assert_eq!(Some(1u32), old);
823    /// # Ok(()) }
824    /// ```
825    pub async fn mutate_key<T, M, R>(&self, key: impl AsRef<Key<T>>, mut mutator: M) -> Option<R>
826    where
827        T: Clone + Any + Send + Sync,
828        M: FnMut(&mut T) -> R,
829    {
830        let key = key.as_ref().as_raw_key();
831        let storage = self.inner.storage.read().await;
832
833        let storage = match storage.get(key) {
834            Some(s) => s,
835            None => return None,
836        };
837
838        let mut value = storage.value.write().await;
839
840        if let Some(value) = &mut *value {
841            let output = mutator(unsafe { value.downcast_mut() });
842            let value = value.clone();
843            let _ = storage.tx.send(Some(value));
844            return Some(output);
845        }
846
847        None
848    }
849
850    /// Get a value from the injector.
851    ///
852    /// # Examples
853    ///
854    /// ```
855    /// use async_injector::Injector;
856    ///
857    /// # #[tokio::main] async fn main() {
858    /// let injector = Injector::new();
859    ///
860    /// assert_eq!(None, injector.get::<u32>().await);
861    /// injector.update(1u32).await;
862    /// assert_eq!(Some(1u32), injector.get::<u32>().await);
863    /// # }
864    /// ```
865    pub async fn get<T>(&self) -> Option<T>
866    where
867        T: Clone + Any + Send + Sync,
868    {
869        self.get_key(Key::<T>::of()).await
870    }
871
872    /// Get a value from the injector with the given key.
873    ///
874    /// # Examples
875    ///
876    /// ```
877    /// use async_injector::{Key, Injector};
878    ///
879    /// # #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> {
880    /// let k1 = Key::<u32>::tagged("first")?;
881    /// let k2 = Key::<u32>::tagged("second")?;
882    ///
883    /// let injector = Injector::new();
884    ///
885    /// assert_eq!(None, injector.get_key(&k1).await);
886    /// assert_eq!(None, injector.get_key(&k2).await);
887    ///
888    /// injector.update_key(&k1, 1u32).await;
889    ///
890    /// assert_eq!(Some(1u32), injector.get_key(&k1).await);
891    /// assert_eq!(None, injector.get_key(&k2).await);
892    /// # Ok(()) }
893    /// ```
894    pub async fn get_key<T>(&self, key: impl AsRef<Key<T>>) -> Option<T>
895    where
896        T: Clone + Any + Send + Sync,
897    {
898        let key = key.as_ref().as_raw_key();
899        let storage = self.inner.storage.read().await;
900
901        let storage = match storage.get(key) {
902            Some(storage) => storage,
903            None => return None,
904        };
905
906        let value = storage.value.read().await;
907
908        value.as_ref().map(|value| {
909            // Safety: Ref<T> instances can only be produced by checked fns.
910            unsafe { value.downcast_ref::<T>().clone() }
911        })
912    }
913
914    /// Wait for a value to become available.
915    ///
916    /// Note that this could potentially wait forever if the value is never
917    /// injected.
918    ///
919    /// # Examples
920    ///
921    /// ```
922    /// use async_injector::Injector;
923    ///
924    /// # #[tokio::main]
925    /// # async fn main() {
926    /// let injector = Injector::new();
927    ///
928    /// injector.update(1u32).await;
929    /// assert_eq!(1u32, injector.wait::<u32>().await);
930    /// # }
931    /// ```
932    #[inline]
933    pub async fn wait<T>(&self) -> T
934    where
935        T: Clone + Any + Send + Sync,
936    {
937        self.wait_key(Key::<T>::of()).await
938    }
939
940    /// Wait for a value associated with the given key to become available.
941    ///
942    /// Note that this could potentially wait forever if the value is never
943    /// injected.
944    ///
945    /// # Examples
946    ///
947    /// ```
948    /// use async_injector::{Key, Injector};
949    ///
950    /// # #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> {
951    /// let injector = Injector::new();
952    /// let tag = Key::<u32>::tagged("first")?;
953    ///
954    /// injector.update_key(&tag, 1u32).await;
955    /// assert_eq!(1u32, injector.wait_key(tag).await);
956    /// # Ok(()) }
957    /// ```
958    pub async fn wait_key<T>(&self, key: impl AsRef<Key<T>>) -> T
959    where
960        T: Clone + Any + Send + Sync,
961    {
962        let (mut stream, value) = self.stream_key(key).await;
963
964        if let Some(value) = value {
965            return value;
966        }
967
968        loop {
969            if let Some(value) = stream.recv().await {
970                return value;
971            }
972        }
973    }
974
975    /// Get an existing value and setup a stream for updates at the same time.
976    ///
977    /// # Examples
978    ///
979    /// ```
980    /// use async_injector::Injector;
981    ///
982    /// #[derive(Debug, Clone, PartialEq, Eq)]
983    /// struct Database;
984    ///
985    /// # #[tokio::main] async fn main() {
986    /// let injector = Injector::new();
987    /// let (mut database_stream, mut database) = injector.stream::<Database>().await;
988    ///
989    /// // Update the key somewhere else.
990    /// tokio::spawn({
991    ///     let injector = injector.clone();
992    ///
993    ///     async move {
994    ///         injector.update(Database).await;
995    ///     }
996    /// });
997    ///
998    /// let database = loop {
999    ///     if let Some(update) = database_stream.recv().await {
1000    ///         break update;
1001    ///     }
1002    /// };
1003    ///
1004    /// assert_eq!(database, Database);
1005    /// # }
1006    /// ```
1007    pub async fn stream<T>(&self) -> (Stream<T>, Option<T>)
1008    where
1009        T: Clone + Any + Send + Sync,
1010    {
1011        self.stream_key(Key::<T>::of()).await
1012    }
1013
1014    /// Get an existing value and setup a stream for updates at the same time.
1015    ///
1016    /// # Examples
1017    ///
1018    /// ```
1019    /// use async_injector::{Key, Injector};
1020    ///
1021    /// #[derive(Debug, Clone, PartialEq, Eq)]
1022    /// struct Database;
1023    ///
1024    /// # #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> {
1025    /// let injector = Injector::new();
1026    /// let db = Key::<Database>::tagged("first")?;
1027    /// let (mut database_stream, mut database) = injector.stream_key(&db).await;
1028    ///
1029    /// // Update the key somewhere else.
1030    /// tokio::spawn({
1031    ///     let db = db.clone();
1032    ///     let injector = injector.clone();
1033    ///
1034    ///     async move {
1035    ///         injector.update_key(&db, Database).await;
1036    ///     }
1037    /// });
1038    ///
1039    /// let database = loop {
1040    ///     if let Some(update) = database_stream.recv().await {
1041    ///         break update;
1042    ///     }
1043    /// };
1044    ///
1045    /// assert_eq!(database, Database);
1046    /// # Ok(()) }
1047    /// ```
1048    pub async fn stream_key<T>(&self, key: impl AsRef<Key<T>>) -> (Stream<T>, Option<T>)
1049    where
1050        T: Clone + Any + Send + Sync,
1051    {
1052        let key = key.as_ref().as_raw_key();
1053
1054        let mut storage = self.inner.storage.write().await;
1055        let storage = storage.entry(key.clone()).or_default();
1056
1057        let rx = storage.tx.subscribe();
1058
1059        let value = storage.value.read().await;
1060
1061        let value = value.as_ref().map(|value| {
1062            // Safety: The expected type parameter is encoded and maintained
1063            // in the Stream type.
1064            unsafe { value.downcast_ref::<T>().clone() }
1065        });
1066
1067        let stream = Stream {
1068            rx,
1069            marker: marker::PhantomData,
1070        };
1071
1072        (stream, value)
1073    }
1074
1075    /// Get a synchronized reference for the given configuration key.
1076    ///
1077    /// # Examples
1078    ///
1079    /// ```
1080    /// use async_injector::Injector;
1081    ///
1082    /// #[derive(Clone)]
1083    /// struct Database;
1084    ///
1085    /// # #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> {
1086    /// let injector = Injector::new();
1087    ///
1088    /// let database = injector.var::<Database>().await;
1089    ///
1090    /// assert!(database.read().await.is_none());
1091    /// injector.update(Database).await;
1092    /// assert!(database.read().await.is_some());
1093    /// # Ok(()) }
1094    /// ```
1095    pub async fn var<T>(&self) -> Ref<T>
1096    where
1097        T: Clone + Any + Send + Sync + Unpin,
1098    {
1099        self.var_key(Key::<T>::of()).await
1100    }
1101
1102    /// Get a synchronized reference for the given configuration key.
1103    ///
1104    /// # Examples
1105    ///
1106    /// ```
1107    /// use async_injector::{Key, Injector};
1108    /// use std::error::Error;
1109    ///
1110    /// #[derive(Clone)]
1111    /// struct Database;
1112    ///
1113    /// # #[tokio::main] async fn main() -> Result<(), Box<dyn Error>> {
1114    /// let injector = Injector::new();
1115    /// let db = Key::<Database>::tagged("first")?;
1116    ///
1117    /// let database = injector.var_key(&db).await;
1118    ///
1119    /// assert!(database.read().await.is_none());
1120    /// injector.update_key(&db, Database).await;
1121    /// assert!(database.read().await.is_some());
1122    /// # Ok(()) }
1123    /// ```
1124    pub async fn var_key<T>(&self, key: impl AsRef<Key<T>>) -> Ref<T>
1125    where
1126        T: Clone + Any + Send + Sync + Unpin,
1127    {
1128        let key = key.as_ref().as_raw_key();
1129
1130        let mut storage = self.inner.storage.write().await;
1131        let storage = storage.entry(key.clone()).or_default();
1132
1133        Ref {
1134            value: storage.value.clone(),
1135            _m: marker::PhantomData,
1136        }
1137    }
1138}
1139
1140impl Default for Injector {
1141    fn default() -> Self {
1142        Self {
1143            inner: Arc::new(Inner {
1144                storage: Default::default(),
1145            }),
1146        }
1147    }
1148}
1149
1150#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
1151struct RawKey {
1152    type_id: TypeId,
1153    tag_type_id: TypeId,
1154    tag: hashkey::Key,
1155}
1156
1157impl RawKey {
1158    /// Construct a new raw key.
1159    fn new<T, K>(tag: hashkey::Key) -> Self
1160    where
1161        T: Any,
1162        K: Any,
1163    {
1164        Self {
1165            type_id: TypeId::of::<T>(),
1166            tag_type_id: TypeId::of::<K>(),
1167            tag,
1168        }
1169    }
1170}
1171
1172/// A key used to discriminate a value in the [`Injector`].
1173#[derive(Clone)]
1174pub struct Key<T>
1175where
1176    T: Any,
1177{
1178    raw_key: RawKey,
1179    _marker: marker::PhantomData<T>,
1180}
1181
1182impl<T> fmt::Debug for Key<T>
1183where
1184    T: Any,
1185{
1186    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1187        fmt::Debug::fmt(&self.raw_key, fmt)
1188    }
1189}
1190
1191impl<T> cmp::PartialEq for Key<T>
1192where
1193    T: Any,
1194{
1195    fn eq(&self, other: &Self) -> bool {
1196        self.as_raw_key().eq(other.as_raw_key())
1197    }
1198}
1199
1200impl<T> cmp::Eq for Key<T> where T: Any {}
1201
1202impl<T> cmp::PartialOrd for Key<T>
1203where
1204    T: Any,
1205{
1206    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
1207        Some(self.cmp(other))
1208    }
1209}
1210
1211impl<T> cmp::Ord for Key<T>
1212where
1213    T: Any,
1214{
1215    fn cmp(&self, other: &Self) -> cmp::Ordering {
1216        self.as_raw_key().cmp(other.as_raw_key())
1217    }
1218}
1219
1220impl<T> hash::Hash for Key<T>
1221where
1222    T: Any,
1223{
1224    fn hash<H>(&self, state: &mut H)
1225    where
1226        H: hash::Hasher,
1227    {
1228        self.as_raw_key().hash(state);
1229    }
1230}
1231
1232impl<T> Key<T>
1233where
1234    T: Any,
1235{
1236    /// Construct a new key without a tag.
1237    ///
1238    /// # Examples
1239    ///
1240    /// ```
1241    /// use async_injector::Key;
1242    ///
1243    /// struct Foo;
1244    ///
1245    /// assert_eq!(Key::<Foo>::of(), Key::<Foo>::of());
1246    /// ```
1247    pub fn of() -> Self {
1248        Self {
1249            raw_key: RawKey::new::<T, ()>(hashkey::Key::Unit),
1250            _marker: marker::PhantomData,
1251        }
1252    }
1253
1254    /// Construct a new key.
1255    ///
1256    /// # Examples
1257    ///
1258    /// ```
1259    /// use serde::Serialize;
1260    /// use async_injector::Key;
1261    ///
1262    /// struct Foo;
1263    ///
1264    /// #[derive(Serialize)]
1265    /// enum Tag {
1266    ///     One,
1267    ///     Two,
1268    /// }
1269    ///
1270    /// #[derive(Serialize)]
1271    /// enum Tag2 {
1272    ///     One,
1273    ///     Two,
1274    /// }
1275    ///
1276    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
1277    /// assert_eq!(Key::<Foo>::tagged(Tag::One)?, Key::<Foo>::tagged(Tag::One)?);
1278    /// assert_ne!(Key::<Foo>::tagged(Tag::One)?, Key::<Foo>::tagged(Tag::Two)?);
1279    /// assert_ne!(Key::<Foo>::tagged(Tag::One)?, Key::<Foo>::tagged(Tag2::One)?);
1280    /// # Ok(()) }
1281    /// ```
1282    pub fn tagged<K>(tag: K) -> Result<Self, Error>
1283    where
1284        K: Any + serde::Serialize,
1285    {
1286        let tag = hashkey::to_key(&tag)?;
1287
1288        Ok(Self {
1289            raw_key: RawKey::new::<T, K>(tag),
1290            _marker: marker::PhantomData,
1291        })
1292    }
1293
1294    /// Convert into a raw key.
1295    fn as_raw_key(&self) -> &RawKey {
1296        &self.raw_key
1297    }
1298}
1299
1300impl<T> AsRef<Key<T>> for Key<T>
1301where
1302    T: 'static,
1303{
1304    fn as_ref(&self) -> &Self {
1305        self
1306    }
1307}
1308
1309/// A variable allowing for the synchronized reading of avalue in the
1310/// [`Injector`].
1311///
1312/// This can be created through [Injector::var] or [Injector::var_key].
1313#[derive(Clone)]
1314pub struct Ref<T>
1315where
1316    T: Clone + Any + Send + Sync,
1317{
1318    value: Arc<RwLock<Option<Value>>>,
1319    _m: marker::PhantomData<T>,
1320}
1321
1322impl<T> Ref<T>
1323where
1324    T: Clone + Any + Send + Sync,
1325{
1326    /// Read the synchronized variable.
1327    ///
1328    /// # Examples
1329    ///
1330    /// ```
1331    /// use async_injector::Injector;
1332    ///
1333    /// #[derive(Clone)]
1334    /// struct Database;
1335    ///
1336    /// # #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> {
1337    /// let injector = Injector::new();
1338    ///
1339    /// let database = injector.var::<Database>().await;
1340    ///
1341    /// assert!(database.read().await.is_none());
1342    /// injector.update(Database).await;
1343    /// assert!(database.read().await.is_some());
1344    /// # Ok(()) }
1345    /// ```
1346    pub async fn read(&self) -> Option<RefReadGuard<'_, T>> {
1347        let value = self.value.read().await;
1348
1349        let result = RefReadGuard::try_map(value, |value| {
1350            value.as_ref().map(|value| {
1351                // Safety: The expected type parameter is encoded and
1352                // maintained in the Stream type.
1353                unsafe { value.downcast_ref::<T>() }
1354            })
1355        });
1356
1357        result.ok()
1358    }
1359
1360    /// Load the synchronized variable. This clones the underlying value if it
1361    /// has been set.
1362    ///
1363    /// # Examples
1364    ///
1365    /// ```
1366    /// use async_injector::Injector;
1367    ///
1368    /// #[derive(Clone)]
1369    /// struct Database;
1370    ///
1371    /// # #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> {
1372    /// let injector = Injector::new();
1373    ///
1374    /// let database = injector.var::<Database>().await;
1375    ///
1376    /// assert!(database.load().await.is_none());
1377    /// injector.update(Database).await;
1378    /// assert!(database.load().await.is_some());
1379    /// # Ok(()) }
1380    /// ```
1381    pub async fn load(&self) -> Option<T> {
1382        let value = self.value.read().await;
1383
1384        value.as_ref().map(|value| {
1385            // Safety: The expected type parameter is encoded and maintained
1386            // in the Stream type.
1387            unsafe { value.downcast_ref::<T>().clone() }
1388        })
1389    }
1390}
1391
1392#[cfg(test)]
1393mod tests {
1394    use super::Value;
1395
1396    #[test]
1397    fn test_clone() {
1398        use std::sync::{
1399            atomic::{AtomicUsize, Ordering},
1400            Arc,
1401        };
1402
1403        let count = Arc::new(AtomicUsize::new(0));
1404
1405        let value = Value::new(Foo(count.clone()));
1406        assert_eq!(0, count.load(Ordering::SeqCst));
1407        drop(value.clone());
1408        assert_eq!(1, count.load(Ordering::SeqCst));
1409        drop(value);
1410        assert_eq!(2, count.load(Ordering::SeqCst));
1411
1412        #[derive(Clone)]
1413        struct Foo(Arc<AtomicUsize>);
1414
1415        impl Drop for Foo {
1416            fn drop(&mut self) {
1417                self.0.fetch_add(1, Ordering::SeqCst);
1418            }
1419        }
1420    }
1421}