ouisync/access_control/
access_mode.rs

1use num_enum::{IntoPrimitive, TryFromPrimitive};
2use ouisync_macros::api;
3use serde::{Deserialize, Serialize};
4use std::{fmt, str::FromStr};
5use thiserror::Error;
6
7/// Access mode of a repository.
8#[derive(
9    Clone,
10    Copy,
11    Eq,
12    PartialEq,
13    Ord,
14    PartialOrd,
15    Debug,
16    Serialize,
17    Deserialize,
18    IntoPrimitive,
19    TryFromPrimitive,
20)]
21#[repr(u8)]
22#[serde(into = "u8", try_from = "u8")]
23#[api]
24pub enum AccessMode {
25    /// Repository is neither readable not writtable (but can still be synced).
26    Blind = 0,
27    /// Repository is readable but not writtable.
28    Read = 1,
29    /// Repository is both readable and writable.
30    Write = 2,
31}
32
33impl AccessMode {
34    pub fn can_read(&self) -> bool {
35        self != &Self::Blind
36    }
37}
38
39impl FromStr for AccessMode {
40    type Err = AccessModeParseError;
41
42    fn from_str(input: &str) -> Result<Self, Self::Err> {
43        match input.chars().next() {
44            Some('b' | 'B') => Ok(AccessMode::Blind),
45            Some('r' | 'R') => Ok(AccessMode::Read),
46            Some('w' | 'W') => Ok(AccessMode::Write),
47            _ => Err(AccessModeParseError),
48        }
49    }
50}
51
52impl fmt::Display for AccessMode {
53    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54        match self {
55            Self::Blind => write!(f, "blind"),
56            Self::Read => write!(f, "read"),
57            Self::Write => write!(f, "write"),
58        }
59    }
60}
61
62#[derive(Debug, Error)]
63#[error("failed to parse access mode")]
64pub struct AccessModeParseError;
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69
70    #[test]
71    fn ord() {
72        assert!(AccessMode::Blind < AccessMode::Read);
73        assert!(AccessMode::Blind < AccessMode::Write);
74        assert!(AccessMode::Read < AccessMode::Write);
75    }
76}