1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
use crate::{InjectResult, Injector, RequestInfo, Service, Svc, TypedProvider}; /// A provider which returns a constant, predetermined value. Note that this is /// technically a singleton service in that it does not recreate the value each /// time it is requested. pub struct ConstantProvider<R> where R: Service, { result: Svc<R>, } impl<R> ConstantProvider<R> where R: Service, { /// Creates a new [`ConstantProvider`] using a predetermined value. #[must_use] pub fn new(value: R) -> Self { ConstantProvider { result: Svc::new(value), } } } impl<R> TypedProvider for ConstantProvider<R> where R: Service, { type Result = R; fn provide_typed( &mut self, _injector: &Injector, _request_info: &RequestInfo, ) -> InjectResult<Svc<Self::Result>> { Ok(self.result.clone()) } } impl<T: Service> From<T> for ConstantProvider<T> { fn from(value: T) -> Self { constant(value) } } /// Create a provider from a constant value. /// /// While the service itself will never be exposed through a mutable reference, /// if it supports interior mutability, its fields still can be mutated. Since /// the provider created with this function doesn't recreate the value each /// time it's requested, state can be stored in this manner. /// /// ## Example /// /// ``` /// use runtime_injector::{constant, Injector, Svc}; /// /// let mut builder = Injector::builder(); /// builder.provide(constant(8i32)); /// /// let injector = builder.build(); /// let value: Svc<i32> = injector.get().unwrap(); /// /// assert_eq!(8, *value); /// ``` /// /// ## Interior mutability /// /// One use case for constant values is to create a mutex to lock static, /// synchronized values that can be accessed from any service. For instance, /// suppose you wanted to create a counter to keep track of how many instances /// of a service you created: /// /// ``` /// use runtime_injector::{constant, Injector, IntoTransient, Svc}; /// use std::sync::Mutex; /// /// struct Foo; /// impl Foo { /// pub fn new(counter: Svc<Mutex<i32>>) -> Self { /// let mut counter = counter.lock().unwrap(); /// *counter += 1; /// Foo /// } /// } /// /// let mut builder = Injector::builder(); /// builder.provide(Foo::new.transient()); /// builder.provide(constant(Mutex::new(0i32))); /// /// let injector = builder.build(); /// let foo: Svc<Foo> = injector.get().unwrap(); /// let value: Svc<Mutex<i32>> = injector.get().unwrap(); /// /// assert_eq!(1, *value.lock().unwrap()); /// ``` pub fn constant<T: Service>(value: T) -> ConstantProvider<T> { ConstantProvider::new(value) }