service_locator/
guard.rs

1use std::ops::{Deref, DerefMut};
2use std::sync::{RwLockReadGuard, RwLockWriteGuard};
3
4/// RAII structure used to release the shared read access to the service when dropped.
5/// 
6/// This structure is created by the [`service`][super::ServiceLocator::service] method on [`ServiceLocator<T>`][super::ServiceLocator].
7#[derive(Debug)]
8pub struct ServiceReadGuard<'a, T: ?Sized + 'a> {
9    service: RwLockReadGuard<'a, Option<Box<T>>>,
10}
11
12impl<'a, T: ?Sized + 'a> ServiceReadGuard<'a, T> {
13    #[inline]
14    pub(crate) fn new(service: RwLockReadGuard<'a, Option<Box<T>>>) -> ServiceReadGuard<'a, T> {
15        Self {
16            service,
17        }
18    }
19}
20
21impl<'a, T: ?Sized> Deref for ServiceReadGuard<'a, T> {
22    type Target = T;
23
24    #[inline]
25    fn deref(&self) -> &Self::Target {
26        // SAFETY: The service is checked not to be None in the ServiceLocator<T>::service() method.
27        self.service.as_ref().unwrap()
28    }
29}
30
31/// RAII structure used to release the exclusive write access to the service when dropped.
32/// 
33/// This structure is created by the [`service_mut`][super::ServiceLocator::service_mut] method on [`ServiceLocator<T>`][super::ServiceLocator].
34#[derive(Debug)]
35pub struct ServiceWriteGuard<'a, T: ?Sized + 'a> {
36    service: RwLockWriteGuard<'a, Option<Box<T>>>,
37}
38
39impl<'a, T: ?Sized> ServiceWriteGuard<'a, T> {
40    #[inline]
41    pub(crate) fn new(service: RwLockWriteGuard<'a, Option<Box<T>>>) -> Self {
42        Self {
43            service,
44        }
45    }
46}
47
48impl<'a, T: ?Sized> Deref for ServiceWriteGuard<'a, T> {
49    type Target = T;
50
51    #[inline]
52    fn deref(&self) -> &Self::Target {
53        // SAFETY: The service is checked not to be None in the ServiceLocator<T>::service_mut() method.
54        self.service.as_ref().unwrap()
55    }
56}
57
58impl<'a, T: ?Sized> DerefMut for ServiceWriteGuard<'a, T> {
59    #[inline]
60    fn deref_mut(&mut self) -> &mut Self::Target {
61        // SAFETY: The service is checked not to be None in the ServiceLocator<T>::service_mut() method.
62        self.service.as_mut().unwrap()
63    }
64}