|
1 | 1 | //! Marker types for limiting access.
|
2 | 2 |
|
3 |
| -/// Sealed trait that is implemented for the types in this module. |
4 |
| -pub trait Access: Copy + Default + private::Sealed { |
5 |
| - /// Reduced access level to safely share the corresponding value. |
6 |
| - type RestrictShared: Access; |
| 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; |
7 | 19 | }
|
8 | 20 |
|
9 |
| -/// Helper trait that is implemented by [`ReadWrite`] and [`ReadOnly`]. |
10 |
| -pub trait Readable: Copy + Default + private::Sealed { |
11 |
| - /// Reduced access level to safely share the corresponding value. |
12 |
| - type RestrictShared: Readable + Access; |
| 21 | +impl<To: Access> RestrictAccess<To> for ReadWrite { |
| 22 | + type Restricted = To; |
13 | 23 | }
|
14 | 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 | + |
| 48 | +/// Sealed trait that is implemented for the types in this module. |
| 49 | +pub trait Access: Copy + Default + private::Sealed {} |
| 50 | + |
| 51 | +/// Helper trait that is implemented by [`ReadWrite`] and [`ReadOnly`]. |
| 52 | +pub trait Readable: Access {} |
| 53 | +impl<A: RestrictAccess<ReadOnly, Restricted = ReadOnly>> Readable for A {} |
| 54 | + |
15 | 55 | /// Helper trait that is implemented by [`ReadWrite`] and [`WriteOnly`].
|
16 |
| -pub trait Writable: Access + private::Sealed {} |
| 56 | +pub trait Writable: Access {} |
| 57 | +impl<A: RestrictAccess<WriteOnly, Restricted = WriteOnly>> Writable for A {} |
17 | 58 |
|
18 | 59 | /// Implemented for access types that permit copying of `VolatileRef`.
|
19 |
| -pub trait Copyable: private::Sealed {} |
20 |
| - |
21 |
| -impl<T> Access for T |
22 |
| -where |
23 |
| - T: Readable + Default + Copy, |
24 |
| -{ |
25 |
| - type RestrictShared = <T as Readable>::RestrictShared; |
26 |
| -} |
| 60 | +pub trait Copyable: Access {} |
| 61 | +impl<A: RestrictAccess<ReadOnly, Restricted = Self>> Copyable for A {} |
27 | 62 |
|
28 | 63 | /// Zero-sized marker type for allowing both read and write access.
|
29 | 64 | #[derive(Debug, Default, Copy, Clone)]
|
30 | 65 | pub struct ReadWrite;
|
31 |
| -impl Readable for ReadWrite { |
32 |
| - type RestrictShared = ReadOnly; |
33 |
| -} |
34 |
| -impl Writable for ReadWrite {} |
| 66 | +impl Access for ReadWrite {} |
35 | 67 |
|
36 | 68 | /// Zero-sized marker type for allowing only read access.
|
37 | 69 | #[derive(Debug, Default, Copy, Clone)]
|
38 | 70 | pub struct ReadOnly;
|
39 |
| -impl Readable for ReadOnly { |
40 |
| - type RestrictShared = ReadOnly; |
41 |
| -} |
42 |
| -impl Copyable for ReadOnly {} |
| 71 | +impl Access for ReadOnly {} |
43 | 72 |
|
44 | 73 | /// Zero-sized marker type for allowing only write access.
|
45 | 74 | #[derive(Debug, Default, Copy, Clone)]
|
46 | 75 | pub struct WriteOnly;
|
47 |
| -impl Access for WriteOnly { |
48 |
| - type RestrictShared = NoAccess; |
49 |
| -} |
50 |
| -impl Writable for WriteOnly {} |
| 76 | +impl Access for WriteOnly {} |
51 | 77 |
|
52 | 78 | /// Zero-sized marker type that grants no access.
|
53 | 79 | #[derive(Debug, Default, Copy, Clone)]
|
54 | 80 | pub struct NoAccess;
|
55 |
| -impl Access for NoAccess { |
56 |
| - type RestrictShared = NoAccess; |
57 |
| -} |
58 |
| -impl Copyable for NoAccess {} |
| 81 | +impl Access for NoAccess {} |
59 | 82 |
|
60 | 83 | mod private {
|
61 | 84 | pub trait Sealed {}
|
|
0 commit comments