1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
//
// Copyright 2023, Colias Group, LLC
//
// SPDX-License-Identifier: BSD-2-Clause
//

pub trait Access: AccessSealed {
    type ReadWitness: Witness;
    type WriteWitness: Witness;
}

#[derive(Copy, Clone)]
pub enum Absurdity {}

impl Absurdity {
    pub(crate) fn absurd<T>(self) -> T {
        match self {}
    }
}

pub trait Witness: Sized + Copy + Unpin {
    const TRY_WITNESS: Option<Self>;
}

impl Witness for () {
    const TRY_WITNESS: Option<Self> = Some(());
}

impl Witness for Absurdity {
    const TRY_WITNESS: Option<Self> = None;
}

pub trait ReadAccess: Access {
    const READ_WITNESS: Self::ReadWitness;
}

pub trait WriteAccess: Access {
    const WRITE_WITNESS: Self::WriteWitness;
}

use sealing::AccessSealed;

mod sealing {
    use super::{ReadOnly, ReadWrite, WriteOnly};

    pub trait AccessSealed {}

    impl AccessSealed for ReadOnly {}
    impl AccessSealed for WriteOnly {}
    impl AccessSealed for ReadWrite {}
}

pub enum ReadOnly {}

impl Access for ReadOnly {
    type ReadWitness = ();
    type WriteWitness = Absurdity;
}

impl ReadAccess for ReadOnly {
    const READ_WITNESS: Self::ReadWitness = ();
}

pub enum WriteOnly {}

impl Access for WriteOnly {
    type ReadWitness = Absurdity;
    type WriteWitness = ();
}

impl WriteAccess for WriteOnly {
    const WRITE_WITNESS: Self::WriteWitness = ();
}

pub enum ReadWrite {}

impl Access for ReadWrite {
    type ReadWitness = ();
    type WriteWitness = ();
}

impl ReadAccess for ReadWrite {
    const READ_WITNESS: Self::ReadWitness = ();
}

impl WriteAccess for ReadWrite {
    const WRITE_WITNESS: Self::WriteWitness = ();
}