Skip to main content

harmos_domain/plugin/
requirement.rs

1/* ***
2 *
3 * Harmos
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * ***
8 */
9
10/* === Modules === */
11
12/* === Re-Exports === */
13
14/* === Imports === */
15
16// Standard Library Imports
17use std::borrow::Cow;
18// Third Party Imports
19use serde::{Deserialize, Serialize};
20// Local Imports
21use crate::catalog::{Member, Visitor};
22use crate::operations::{Declares, OperationDeclaration, WireDeclaration};
23
24/* === Constants === */
25
26/* === Macros === */
27
28/* === Type Aliases === */
29
30/* === Structs === */
31
32// Permission to call one operation. An operation whose request names a channel,
33// stream or source resolves it to `scope`; any other operation is granted by
34// its id alone, which holding its requirement already confers.
35#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
36#[serde(rename_all = "snake_case", deny_unknown_fields)]
37pub struct Grant {
38    pub operation: Cow<'static, str>,
39
40    #[serde(default, skip_serializing_if = "Option::is_none")]
41    pub scope: Option<Cow<'static, str>>,
42}
43
44pub struct Requirement {
45    pub declaration: WireDeclaration,
46    pub grants: &'static [Grant],
47}
48
49pub struct Requirements;
50
51/* === Enums === */
52
53/* === Traits === */
54
55/* === Implementations === */
56
57impl Requirement {
58    pub const fn of<O: OperationDeclaration>(grants: &'static [Grant]) -> Self {
59        Self { declaration: WireDeclaration::of::<O>(), grants }
60    }
61}
62
63impl Grant {
64    pub fn of(operation: impl Into<Cow<'static, str>>, scope: impl Into<Cow<'static, str>>) -> Self {
65        Self { operation: operation.into(), scope: Some(scope.into()) }
66    }
67
68    pub fn operation(&self) -> &str {
69        &self.operation
70    }
71
72    pub fn scope(&self) -> Option<&str> {
73        self.scope.as_deref()
74    }
75
76    pub(crate) const fn borrowed(&self) -> (&'static str, Option<&'static str>) {
77        let operation = match &self.operation {
78            Cow::Borrowed(value) => *value,
79            Cow::Owned(_) => panic!("const grants must be borrowed"),
80        };
81        let scope = match &self.scope {
82            None => None,
83            Some(Cow::Borrowed(value)) => Some(*value),
84            Some(Cow::Owned(_)) => panic!("const grants must be borrowed"),
85        };
86        (operation, scope)
87    }
88}
89
90impl Visitor for Requirements {
91    type Entry = Requirement;
92}
93
94impl<M> Member<M> for Requirements
95where
96    M: Declares,
97{
98    const ENTRY: Requirement = Requirement::of::<M::Declaration>(&[]);
99}
100
101/* === Public Functions === */
102
103/* === Private Functions === */
104
105/* === Tests === */