1use std::collections::HashMap;
2
3#[derive(Debug, Default, Clone)]
5pub struct Request {
6 action: String,
7 actor_attrs: HashMap<String, String>,
8 resource_attrs: HashMap<String, String>,
9 environment_attrs: HashMap<String, String>,
10}
11
12impl Request {
13 pub fn new() -> Self {
15 Self::default()
16 }
17
18 pub fn action(mut self, action: impl Into<String>) -> Self {
20 self.action = action.into();
21 self
22 }
23
24 pub fn actor_attr(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
26 self.actor_attrs.insert(key.into(), value.into());
27 self
28 }
29
30 pub fn resource_attr(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
32 self.resource_attrs.insert(key.into(), value.into());
33 self
34 }
35
36 pub fn environment_attr(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
38 self.environment_attrs.insert(key.into(), value.into());
39 self
40 }
41
42 pub fn action_name(&self) -> &str {
44 &self.action
45 }
46
47 pub(crate) fn lookup(&self, namespace: &str, key: Option<&str>) -> Option<&str> {
48 match namespace {
49 "actor" => key.and_then(|k| self.actor_attrs.get(k)).map(String::as_str),
50 "resource" => key
51 .and_then(|k| self.resource_attrs.get(k))
52 .map(String::as_str),
53 "environment" => key
54 .and_then(|k| self.environment_attrs.get(k))
55 .map(String::as_str),
56 "action" => {
57 if let Some("name") | Some("id") = key {
58 Some(self.action.as_str())
59 } else if key.is_none() {
60 Some(self.action.as_str())
61 } else {
62 None
63 }
64 }
65 _ => None,
66 }
67 }
68}