four/iam/property/
statement.rs1use crate::iam::property::{action::Action, effect::Effect, principal::Principal};
2use serde::{ser::SerializeMap, Serialize};
3
4#[derive(Debug, Clone)]
5pub struct Statement {
6 effect: Effect,
7 action: ActionOr,
8 principal: Option<PrincipalOr>,
9 resource: Option<String>,
10}
11
12impl Statement {
13 pub fn allow_actions(actions: Vec<Box<dyn Action>>) -> StatementBuilder {
14 StatementBuilder {
15 effect: Effect::Allow,
16 action: ActionOr::Action(actions),
17 principal: None,
18 resource: None,
19 }
20 }
21
22 pub fn deny_actions(actions: Vec<Box<dyn Action>>) -> StatementBuilder {
23 StatementBuilder {
24 effect: Effect::Deny,
25 action: ActionOr::Action(actions),
26 principal: None,
27 resource: None,
28 }
29 }
30
31 pub fn allow_no_actions(actions: Vec<Box<dyn Action>>) -> StatementBuilder {
32 StatementBuilder {
33 effect: Effect::Allow,
34 action: ActionOr::NotAction(actions),
35 principal: None,
36 resource: None,
37 }
38 }
39
40 pub fn deny_no_actions(actions: Vec<Box<dyn Action>>) -> StatementBuilder {
41 StatementBuilder {
42 effect: Effect::Deny,
43 action: ActionOr::NotAction(actions),
44 principal: None,
45 resource: None,
46 }
47 }
48}
49
50impl Serialize for Statement {
51 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
52 where
53 S: serde::Serializer,
54 {
55 let mut map = serializer.serialize_map(None)?;
56 map.serialize_entry("Effect", &self.effect)?;
57 match &self.action {
58 ActionOr::Action(action) => map.serialize_entry("Action", action)?,
59 ActionOr::NotAction(action) => map.serialize_entry("NotAction", action)?,
60 }
61 if let Some(principal) = self.principal.as_ref() {
62 match principal {
63 PrincipalOr::Principal(p) => map.serialize_entry("Principal", p)?,
64 PrincipalOr::NotPrincipal(p) => map.serialize_entry("NotPrincipal", p)?,
65 }
66 }
67 if let Some(resource) = self.resource.as_ref() {
68 map.serialize_entry("Resource", resource)?;
69 }
70
71 map.end()
72 }
73}
74
75#[derive(Debug)]
76pub struct StatementBuilder {
77 effect: Effect,
78 action: ActionOr,
79 principal: Option<PrincipalOr>,
80 resource: Option<String>,
81}
82
83impl StatementBuilder {
84 pub fn build(self) -> Result<Statement, StatementBuildError> {
85 let statement = Statement {
88 effect: self.effect,
89 action: self.action,
90 principal: self.principal,
91 resource: self.resource,
92 };
93
94 Ok(statement)
95 }
96
97 pub fn principal(mut self, principal: Principal) -> Self {
98 self.principal = Some(PrincipalOr::Principal(principal));
99 self
100 }
101
102 pub fn no_principal(mut self, principal: Principal) -> Self {
103 self.principal = Some(PrincipalOr::NotPrincipal(principal));
104 self
105 }
106
107 pub fn resource(mut self, resource: &str) -> Self {
108 self.resource = Some(resource.to_string());
109 self
110 }
111}
112
113#[derive(Debug, thiserror::Error)]
114pub enum StatementBuildError {}
115
116#[derive(Debug, Clone)]
117pub enum ActionOr {
118 Action(Vec<Box<dyn Action>>),
119 NotAction(Vec<Box<dyn Action>>),
120}
121
122#[derive(Debug, Clone)]
123pub enum PrincipalOr {
124 Principal(Principal),
125 NotPrincipal(Principal),
126}