policy/
lib.rs

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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use core::fmt::Debug;
use std::fmt::Display;
use std::future::Future;

use chrono::{DateTime, Local};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct PolicyContent {
    pub reasoner: String,
    pub reasoner_version: String,
    pub content: Box<serde_json::value::RawValue>,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct PolicyVersion {
    pub creator: Option<String>,
    pub created_at: DateTime<Local>,
    pub version: Option<i64>,
    pub version_description: String,
    /// reasoner_connector_context contains the hash of the reasoner connector's base definitions
    pub reasoner_connector_context: String,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ActivePolicy {
    pub version: String,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Policy {
    pub description: String,
    #[serde(flatten)]
    pub version:     PolicyVersion,
    pub content:     Vec<PolicyContent>,
}

#[derive(Debug)]
pub enum PolicyDataError {
    NotFound,
    GeneralError(String),
}

impl Display for PolicyDataError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            PolicyDataError::NotFound => write!(f, "PolicyData error: Item not found"),
            PolicyDataError::GeneralError(err) => write!(f, "PolicyData general error: {}", err),
        }
    }
}

impl std::error::Error for PolicyDataError {}

impl warp::reject::Reject for PolicyDataError {}

// impl std::error::Error for PolicyDataError {
//     fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
//         match self {
//             PolicyDataError::NotFound => Some(err),
//             PolicyDataError::GeneralError() => todo!(),
//         }
//     }
// }

// pub trait Transaction {
//     pub fn cancel(self) -> Result<(), Error> {
//         // Do the rollback
//         //...

//         // Drop self _without_ calling its `drop()`
//         std::mem::forget(self);
//     }
//     pub fn accept(self) -> Result<Policy, Error> {
//         // Do the rollback
//         //...

//         // Drop self _without_ calling its `drop()`
//         std::mem::forget(self);
//     }
// }
// impl Drop {
//     fn drop(&mut self) {
//         // Do commit
//         panic!("should not be called implicit, user should execute cancel or accept")
//     }
// }

pub struct Context {
    pub initiator: String,
}

#[async_trait::async_trait]
pub trait PolicyDataAccess {
    type Error;
    #[must_use]
    async fn add_version<F: 'static + Send + Future<Output = Result<(), PolicyDataError>>>(
        &self,
        version: Policy,
        context: Context,
        transaction: impl 'static + Send + FnOnce(Policy) -> F,
    ) -> Result<Policy, PolicyDataError>;
    async fn get_version(&self, version: i64) -> Result<Policy, PolicyDataError>;
    async fn get_most_recent(&self) -> Result<Policy, PolicyDataError>;
    async fn get_versions(&self) -> Result<Vec<PolicyVersion>, PolicyDataError>;
    async fn get_active(&self) -> Result<Policy, PolicyDataError>;
    #[must_use]
    async fn set_active<F: 'static + Send + Future<Output = Result<(), PolicyDataError>>>(
        &self,
        version: i64,
        context: Context,
        transaction: impl 'static + Send + FnOnce(Policy) -> F,
    ) -> Result<Policy, PolicyDataError>;
    #[must_use]
    async fn deactivate_policy<F: 'static + Send + Future<Output = Result<(), PolicyDataError>>>(
        &self,
        context: Context,
        transaction: impl 'static + Send + FnOnce() -> F,
    ) -> Result<(), PolicyDataError>;
}