1
use std::{
2
    borrow::Cow,
3
    fmt::{Display, Write},
4
};
5

            
6
use serde::{Deserialize, Serialize};
7

            
8
/// An action that can be allowed or disallowed.
9
pub trait Action: Send + Sync {
10
    /// The full name of this action.
11
    fn name(&self) -> ActionName;
12
}
13

            
14
impl Action for () {
15
    fn name(&self) -> ActionName {
16
        ActionName::default()
17
    }
18
}
19

            
20
impl Action for ActionName {
21
1
    fn name(&self) -> ActionName {
22
1
        self.clone()
23
1
    }
24
}
25

            
26
/// A unique name of an action.
27
1
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
28
#[allow(clippy::module_name_repetitions)] // exported without the module name
29
pub struct ActionName(pub Vec<Cow<'static, str>>);
30

            
31
impl Display for ActionName {
32
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33
        for (index, name) in self.0.iter().enumerate() {
34
            if index > 0 {
35
                f.write_char('.')?;
36
            }
37

            
38
            name.fmt(f)?;
39
        }
40
        Ok(())
41
    }
42
}
43

            
44
pub use actionable_macros::Action;