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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
use std::sync::Arc;

use tokio::sync::OwnedSemaphorePermit as OwnedSemaphoreBasePermit;
use tokio::sync::Semaphore as SemaphoreBase;
use tokio::sync::SemaphorePermit as SemaphoreBasePermit;

/// Represents a permit to a [Semaphore].
pub struct SemaphorePermit<'a> {
    _permit: SemaphoreBasePermit<'a>,
}

/// Represents an owned permit to a [Semaphore].
pub struct OwnedSemaphorePermit {
    _permit: OwnedSemaphoreBasePermit,
}

/// Error when there are no permits available.
#[derive(Debug)]
pub struct NoPermits;

/// A semaphore maintains a set of permits. Permits are used to synchronize access to a shared resource.
/// A semaphore differs from a mutex in that it can allow more than one concurrent caller to access the shared resource at a time.
#[repr(transparent)]
pub struct Semaphore {
    inner: SemaphoreBase,
}

/// An owned semaphore is identical to a [Semaphore] except it can be owned by an actor and it's permits can still be shared externally.
#[repr(transparent)]
pub struct OwnedSemaphore {
    inner: Arc<SemaphoreBase>,
}

impl Semaphore {
    /// Creates a new instance of [Semaphore] with the given `permits` count.
    ///
    /// This is typically used to create a static semaphore:
    /// ```
    /// use hydra::Semaphore;
    ///
    /// static RATE_LIMIT: Semaphore = Semaphore::new(100);
    /// ```
    pub const fn new(permits: usize) -> Self {
        Self {
            inner: SemaphoreBase::const_new(permits),
        }
    }

    /// Acquires one permit asynchronously waiting for one to become available.
    #[must_use]
    pub async fn acquire(&self) -> SemaphorePermit {
        let permit = self.inner.acquire().await.unwrap();

        SemaphorePermit { _permit: permit }
    }

    /// Acquires many permits asynchronously waiting for them to become available.
    #[must_use]
    pub async fn acquire_many(&self, count: u32) -> SemaphorePermit {
        let permit = self.inner.acquire_many(count).await.unwrap();

        SemaphorePermit { _permit: permit }
    }

    /// Attempts to acquire a permit, returning an error if there are none available.
    pub fn try_acquire(&self) -> Result<SemaphorePermit, NoPermits> {
        let permit = self.inner.try_acquire().map_err(|_| NoPermits)?;

        Ok(SemaphorePermit { _permit: permit })
    }
}

impl OwnedSemaphore {
    /// Creates a new instance of [OwnedSemaphore] with the given `permits` count that can be used with owned permits.
    ///
    /// This can be used to create a owned semaphore that lives in a state:
    /// ```
    /// use hydra::OwnedSemaphore;
    ///
    /// struct MyServer {
    ///     rate_limit: OwnedSemaphore,
    /// }
    ///
    /// impl MyServer {
    ///     pub fn new() -> Self {
    ///         Self {
    ///             rate_limit: OwnedSemaphore::new(100),
    ///         }
    ///     }
    /// }
    /// ```
    pub fn new(permits: usize) -> Self {
        Self {
            inner: Arc::new(SemaphoreBase::new(permits)),
        }
    }

    /// Acquires one permit asynchronously waiting for one to become available.
    #[must_use]
    pub async fn acquire(&self) -> SemaphorePermit {
        let permit = self.inner.acquire().await.unwrap();

        SemaphorePermit { _permit: permit }
    }

    /// Acquires one permit asynchronously waiting for one to become available.
    #[must_use]
    pub async fn acquire_owned(&self) -> OwnedSemaphorePermit {
        let permit = self.inner.clone().acquire_owned().await.unwrap();

        OwnedSemaphorePermit { _permit: permit }
    }

    /// Acquires many permits asynchronously waiting for them to become available.
    #[must_use]
    pub async fn acquire_many(&self, count: u32) -> SemaphorePermit {
        let permit = self.inner.acquire_many(count).await.unwrap();

        SemaphorePermit { _permit: permit }
    }

    /// Acquires many permits asynchronously waiting for them to become available.
    #[must_use]
    pub async fn acquire_many_owned(&self, count: u32) -> OwnedSemaphorePermit {
        let permit = self.inner.clone().acquire_many_owned(count).await.unwrap();

        OwnedSemaphorePermit { _permit: permit }
    }

    /// Attempts to acquire a permit, returning an error if there are none available.
    pub fn try_acquire(&self) -> Result<SemaphorePermit, NoPermits> {
        let permit = self.inner.try_acquire().map_err(|_| NoPermits)?;

        Ok(SemaphorePermit { _permit: permit })
    }

    /// Attempts to acquire a permit, returning an error if there are none available.
    pub fn try_acquire_owned(&self) -> Result<OwnedSemaphorePermit, NoPermits> {
        let permit = self
            .inner
            .clone()
            .try_acquire_owned()
            .map_err(|_| NoPermits)?;

        Ok(OwnedSemaphorePermit { _permit: permit })
    }
}