sel4_abstract_ptr/
access.rs

1//
2// Copyright (c) 2020 Philipp Oppermann
3//
4// SPDX-License-Identifier: MIT OR Apache-2.0
5//
6
7//! Marker types for limiting access.
8
9/// A trait for restricting one [`Access`] type to another [`Access`] type.
10///
11/// Restricting `Self` to `To` results in [`Self::Restricted`].
12///
13/// Restriction is a symmetric operation which is denoted by ∩, as it is the intersection of permissions.
14/// The following table holds:
15///
16/// | `Self`        | `To`          | `Self` ∩ `To` |
17/// | ------------- | ------------- | ------------- |
18/// | `T`           | `T`           | `T`           |
19/// | [`ReadWrite`] | `T`           | `T`           |
20/// | [`NoAccess`]  | `T`           | [`NoAccess`]  |
21/// | [`ReadOnly`]  | [`WriteOnly`] | [`NoAccess`]  |
22pub trait RestrictAccess<To>: Access {
23    /// The resulting [`Access`] type of `Self` restricted to `To`.
24    type Restricted: Access;
25}
26
27impl<To: Access> RestrictAccess<To> for ReadWrite {
28    type Restricted = To;
29}
30
31impl<To> RestrictAccess<To> for NoAccess {
32    type Restricted = Self;
33}
34
35// Sadly, we cannot provide more generic implementations, since they would overlap.
36macro_rules! restrict_impl {
37    ($SelfT:ty, $To:ty, $Restricted:ty) => {
38        impl RestrictAccess<$To> for $SelfT {
39            type Restricted = $Restricted;
40        }
41    };
42}
43
44restrict_impl!(ReadOnly, ReadWrite, ReadOnly);
45restrict_impl!(ReadOnly, ReadOnly, ReadOnly);
46restrict_impl!(ReadOnly, WriteOnly, NoAccess);
47restrict_impl!(ReadOnly, NoAccess, NoAccess);
48
49restrict_impl!(WriteOnly, ReadWrite, WriteOnly);
50restrict_impl!(WriteOnly, ReadOnly, NoAccess);
51restrict_impl!(WriteOnly, WriteOnly, WriteOnly);
52restrict_impl!(WriteOnly, NoAccess, NoAccess);
53
54/// Sealed trait that is implemented for the types in this module.
55pub trait Access: Copy + Default + private::Sealed {}
56
57/// Helper trait that is implemented by [`ReadWrite`] and [`ReadOnly`].
58pub trait Readable: Access {}
59impl<A: RestrictAccess<ReadOnly, Restricted = ReadOnly>> Readable for A {}
60
61/// Helper trait that is implemented by [`ReadWrite`] and [`WriteOnly`].
62pub trait Writable: Access {}
63impl<A: RestrictAccess<WriteOnly, Restricted = WriteOnly>> Writable for A {}
64
65/// Implemented for access types that permit copying of `AbstractRef`.
66pub trait Copyable: Access {}
67impl<A: RestrictAccess<ReadOnly, Restricted = Self>> Copyable for A {}
68
69/// Zero-sized marker type for allowing both read and write access.
70#[derive(Debug, Default, Copy, Clone)]
71pub struct ReadWrite;
72impl Access for ReadWrite {}
73
74/// Zero-sized marker type for allowing only read access.
75#[derive(Debug, Default, Copy, Clone)]
76pub struct ReadOnly;
77impl Access for ReadOnly {}
78
79/// Zero-sized marker type for allowing only write access.
80#[derive(Debug, Default, Copy, Clone)]
81pub struct WriteOnly;
82impl Access for WriteOnly {}
83
84/// Zero-sized marker type that grants no access.
85#[derive(Debug, Default, Copy, Clone)]
86pub struct NoAccess;
87impl Access for NoAccess {}
88
89mod private {
90    pub trait Sealed {}
91
92    impl Sealed for super::ReadWrite {}
93    impl Sealed for super::ReadOnly {}
94    impl Sealed for super::WriteOnly {}
95    impl Sealed for super::NoAccess {}
96}