Skip to content

Commit 7d6a147

Browse files
committed
feat(access): add RestrictAccess<To>
Signed-off-by: Martin Kröning <[email protected]>
1 parent e334f2a commit 7d6a147

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

src/access.rs

+45
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,50 @@
11
//! Marker types for limiting access.
22
3+
/// A trait for restricting one [`Access`] type to another [`Access`] type.
4+
///
5+
/// Restricting `Self` to `To` results in [`Self::Restricted`].
6+
///
7+
/// Restriction is a symmetric operation which is denoted by ∩, as it is the intersection of permissions.
8+
/// The following table holds:
9+
///
10+
/// | `Self` | `To` | `Self` ∩ `To` |
11+
/// | ------------- | ------------- | ------------- |
12+
/// | `T` | `T` | `T` |
13+
/// | [`ReadWrite`] | `T` | `T` |
14+
/// | [`NoAccess`] | `T` | [`NoAccess`] |
15+
/// | [`ReadOnly`] | [`WriteOnly`] | [`NoAccess`] |
16+
pub trait RestrictAccess<To>: Access {
17+
/// The resulting [`Access`] type of `Self` restricted to `To`.
18+
type Restricted: Access;
19+
}
20+
21+
impl<To: Access> RestrictAccess<To> for ReadWrite {
22+
type Restricted = To;
23+
}
24+
25+
impl<To> RestrictAccess<To> for NoAccess {
26+
type Restricted = Self;
27+
}
28+
29+
// Sadly, we cannot provide more generic implementations, since they would overlap.
30+
macro_rules! restrict_impl {
31+
($SelfT:ty, $To:ty, $Restricted:ty) => {
32+
impl RestrictAccess<$To> for $SelfT {
33+
type Restricted = $Restricted;
34+
}
35+
};
36+
}
37+
38+
restrict_impl!(ReadOnly, ReadWrite, ReadOnly);
39+
restrict_impl!(ReadOnly, ReadOnly, ReadOnly);
40+
restrict_impl!(ReadOnly, WriteOnly, NoAccess);
41+
restrict_impl!(ReadOnly, NoAccess, NoAccess);
42+
43+
restrict_impl!(WriteOnly, ReadWrite, WriteOnly);
44+
restrict_impl!(WriteOnly, ReadOnly, NoAccess);
45+
restrict_impl!(WriteOnly, WriteOnly, WriteOnly);
46+
restrict_impl!(WriteOnly, NoAccess, NoAccess);
47+
348
/// Sealed trait that is implemented for the types in this module.
449
pub trait Access: Copy + Default + private::Sealed {
550
/// Reduced access level to safely share the corresponding value.

0 commit comments

Comments
 (0)