1use std::sync::Arc;
2
3use crate::{IsCloseable, Semaphore, SemaphoreState, Uncloseable, drop_wrapper::DropWrapper};
4
5#[must_use]
8pub struct Permit<'a, S, C = Uncloseable>
9where
10 S: SemaphoreState + ?Sized,
11 C: IsCloseable,
12{
13 inner: DropWrapper<SemWrapper<'a, S, C>>,
14}
15
16impl<S, C> core::fmt::Debug for Permit<'_, S, C>
17where
18 S: SemaphoreState + ?Sized,
19 C: IsCloseable,
20 S::Permit: core::fmt::Debug,
21{
22 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
23 f.debug_struct("Permit")
24 .field("permit", &self.inner.t)
25 .finish_non_exhaustive()
26 }
27}
28
29impl<S, C> core::ops::Deref for Permit<'_, S, C>
30where
31 S: SemaphoreState + ?Sized,
32 C: IsCloseable,
33{
34 type Target = S::Permit;
35 fn deref(&self) -> &Self::Target {
36 &self.inner.t
37 }
38}
39
40impl<S, C> core::ops::DerefMut for Permit<'_, S, C>
41where
42 S: SemaphoreState + ?Sized,
43 C: IsCloseable,
44{
45 fn deref_mut(&mut self) -> &mut Self::Target {
46 &mut self.inner.t
47 }
48}
49
50impl<'a, S, C> Permit<'a, S, C>
51where
52 S: SemaphoreState + ?Sized,
53 C: IsCloseable,
54{
55 pub fn out_of_thin_air(sem: &'a Semaphore<S, C>, permit: S::Permit) -> Self {
62 Self {
63 inner: DropWrapper::new(SemWrapper { sem }, permit),
64 }
65 }
66
67 pub fn semaphore(this: &Self) -> &'a Semaphore<S, C> {
69 this.inner.s.sem
70 }
71
72 pub fn take(this: Self) -> S::Permit {
74 this.inner.take()
75 }
76
77 pub fn into_owned_permit(self, sem: Arc<Semaphore<S, C>>) -> OwnedPermit<S, C> {
79 debug_assert_eq!(
80 Arc::as_ptr(&sem),
81 core::ptr::from_ref(Self::semaphore(&self)),
82 "semaphore mismatch!"
83 );
84 OwnedPermit {
85 inner: DropWrapper::new(SemWrapperOwned { sem }, Self::take(self)),
86 }
87 }
88}
89
90struct SemWrapper<'a, S: SemaphoreState + ?Sized, C: IsCloseable> {
91 sem: &'a Semaphore<S, C>,
92}
93
94impl<S: SemaphoreState + ?Sized, C: IsCloseable> crate::drop_wrapper::Drop2
95 for SemWrapper<'_, S, C>
96{
97 type T = S::Permit;
98
99 fn drop(&mut self, permit: Self::T) {
100 self.sem.with_state(|s| s.release(permit));
101 }
102}
103
104#[must_use]
107pub struct OwnedPermit<S, C = Uncloseable>
108where
109 S: SemaphoreState + ?Sized,
110 C: IsCloseable,
111{
112 inner: DropWrapper<SemWrapperOwned<S, C>>,
113}
114
115impl<S, C> core::fmt::Debug for OwnedPermit<S, C>
116where
117 S: SemaphoreState + ?Sized,
118 C: IsCloseable,
119 S::Permit: core::fmt::Debug,
120{
121 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
122 f.debug_struct("Permit")
123 .field("permit", &self.inner.t)
124 .finish_non_exhaustive()
125 }
126}
127
128impl<S, C> core::ops::Deref for OwnedPermit<S, C>
129where
130 S: SemaphoreState + ?Sized,
131 C: IsCloseable,
132{
133 type Target = S::Permit;
134 fn deref(&self) -> &Self::Target {
135 &self.inner.t
136 }
137}
138
139impl<S, C> core::ops::DerefMut for OwnedPermit<S, C>
140where
141 S: SemaphoreState + ?Sized,
142 C: IsCloseable,
143{
144 fn deref_mut(&mut self) -> &mut Self::Target {
145 &mut self.inner.t
146 }
147}
148
149impl<S, C> OwnedPermit<S, C>
150where
151 S: SemaphoreState + ?Sized,
152 C: IsCloseable,
153{
154 pub fn out_of_thin_air(sem: Arc<Semaphore<S, C>>, permit: S::Permit) -> Self {
161 Self {
162 inner: DropWrapper::new(SemWrapperOwned { sem }, permit),
163 }
164 }
165
166 pub fn semaphore(this: &Self) -> &Arc<Semaphore<S, C>> {
168 &this.inner.s.sem
169 }
170
171 pub fn take(this: Self) -> S::Permit {
173 this.inner.take()
174 }
175}
176
177struct SemWrapperOwned<S: SemaphoreState + ?Sized, C: IsCloseable> {
178 sem: Arc<Semaphore<S, C>>,
179}
180
181impl<S: SemaphoreState + ?Sized, C: IsCloseable> crate::drop_wrapper::Drop2
182 for SemWrapperOwned<S, C>
183{
184 type T = S::Permit;
185
186 fn drop(&mut self, permit: Self::T) {
187 self.sem.with_state(|s| s.release(permit));
188 }
189}