pgdo/coordinate/
resource.rs1use super::{lock, CoordinateError, Subject};
15use either::{Either, Left, Right};
16
17pub trait FacetFree {
20 type FacetFree<'a>
21 where
22 Self: 'a;
23
24 fn facet_free(&self) -> Self::FacetFree<'_>;
25}
26
27pub trait FacetShared {
28 type FacetShared<'a>
29 where
30 Self: 'a;
31
32 fn facet_shared(&self) -> Self::FacetShared<'_>;
33}
34
35pub trait FacetExclusive {
36 type FacetExclusive<'a>
37 where
38 Self: 'a;
39
40 fn facet_exclusive(&self) -> Self::FacetExclusive<'_>;
41}
42
43pub struct ResourceFree<S: Subject> {
47 lock: lock::UnlockedFile,
48 subject: S,
49}
50
51impl<S: Subject> ResourceFree<S> {
52 pub fn new(lock: lock::UnlockedFile, inner: S) -> Self {
53 Self { lock, subject: inner }
54 }
55
56 pub fn try_shared(self) -> Result<Either<Self, ResourceShared<S>>, CoordinateError<S::Error>> {
58 Ok(match self.lock.try_lock_shared()? {
59 Left(lock) => Left(Self { subject: self.subject, lock }),
60 Right(lock) => Right(ResourceShared { subject: self.subject, lock }),
61 })
62 }
63
64 pub fn shared(self) -> Result<ResourceShared<S>, CoordinateError<S::Error>> {
66 let lock = self.lock.lock_shared()?;
67 Ok(ResourceShared { subject: self.subject, lock })
68 }
69
70 pub fn try_exclusive(
72 self,
73 ) -> Result<Either<Self, ResourceExclusive<S>>, CoordinateError<S::Error>> {
74 Ok(match self.lock.try_lock_exclusive()? {
75 Left(lock) => Left(Self { subject: self.subject, lock }),
76 Right(lock) => Right(ResourceExclusive { subject: self.subject, lock }),
77 })
78 }
79
80 pub fn exclusive(self) -> Result<ResourceExclusive<S>, CoordinateError<S::Error>> {
82 let lock = self.lock.lock_exclusive()?;
83 Ok(ResourceExclusive { subject: self.subject, lock })
84 }
85
86 pub fn into_parts(self) -> (lock::UnlockedFile, S) {
89 (self.lock, self.subject)
90 }
91}
92
93impl<S: Subject + FacetFree> ResourceFree<S> {
94 pub fn facet(&self) -> S::FacetFree<'_> {
96 self.subject.facet_free()
97 }
98}
99
100pub struct ResourceShared<S: Subject> {
104 lock: lock::LockedFileShared,
105 subject: S,
106}
107
108impl<S: Subject> ResourceShared<S> {
109 pub fn new(lock: lock::LockedFileShared, inner: S) -> Self {
110 Self { lock, subject: inner }
111 }
112
113 pub fn try_exclusive(
115 self,
116 ) -> Result<Either<Self, ResourceExclusive<S>>, CoordinateError<S::Error>> {
117 Ok(match self.lock.try_lock_exclusive()? {
118 Left(lock) => Left(Self { subject: self.subject, lock }),
119 Right(lock) => Right(ResourceExclusive { subject: self.subject, lock }),
120 })
121 }
122
123 pub fn exclusive(self) -> Result<ResourceExclusive<S>, CoordinateError<S::Error>> {
125 let lock = self.lock.lock_exclusive()?;
126 Ok(ResourceExclusive { subject: self.subject, lock })
127 }
128
129 pub fn try_release(self) -> Result<Either<Self, ResourceFree<S>>, CoordinateError<S::Error>> {
131 Ok(match self.lock.try_unlock()? {
132 Left(lock) => Left(Self { subject: self.subject, lock }),
133 Right(lock) => Right(ResourceFree { subject: self.subject, lock }),
134 })
135 }
136
137 pub fn release(self) -> Result<ResourceFree<S>, CoordinateError<S::Error>> {
139 let lock = self.lock.unlock()?;
140 Ok(ResourceFree { subject: self.subject, lock })
141 }
142}
143
144impl<S: Subject + FacetShared> ResourceShared<S> {
145 pub fn facet(&self) -> S::FacetShared<'_> {
147 self.subject.facet_shared()
148 }
149}
150
151pub struct ResourceExclusive<S: Subject> {
155 lock: lock::LockedFileExclusive,
156 subject: S,
157}
158
159impl<S: Subject> ResourceExclusive<S> {
160 pub fn new(lock: lock::LockedFileExclusive, inner: S) -> Self {
161 Self { lock, subject: inner }
162 }
163
164 pub fn try_shared(self) -> Result<Either<Self, ResourceShared<S>>, CoordinateError<S::Error>> {
166 Ok(match self.lock.try_lock_shared()? {
167 Left(lock) => Left(Self { subject: self.subject, lock }),
168 Right(lock) => Right(ResourceShared { subject: self.subject, lock }),
169 })
170 }
171
172 pub fn shared(self) -> Result<ResourceShared<S>, CoordinateError<S::Error>> {
174 let lock = self.lock.lock_shared()?;
175 Ok(ResourceShared { subject: self.subject, lock })
176 }
177
178 pub fn try_release(self) -> Result<Either<Self, ResourceFree<S>>, CoordinateError<S::Error>> {
180 Ok(match self.lock.try_unlock()? {
181 Left(lock) => Left(Self { subject: self.subject, lock }),
182 Right(lock) => Right(ResourceFree { subject: self.subject, lock }),
183 })
184 }
185
186 pub fn release(self) -> Result<ResourceFree<S>, CoordinateError<S::Error>> {
188 let lock = self.lock.unlock()?;
189 Ok(ResourceFree { subject: self.subject, lock })
190 }
191}
192
193impl<S: Subject + FacetExclusive> ResourceExclusive<S> {
194 pub fn facet(&self) -> S::FacetExclusive<'_> {
196 self.subject.facet_exclusive()
197 }
198}