use std::collections::HashMap;
#[derive(Debug, Default, Clone)]
pub struct Request {
action: String,
actor_attrs: HashMap<String, String>,
resource_attrs: HashMap<String, String>,
environment_attrs: HashMap<String, String>,
}
impl Request {
pub fn new() -> Self {
Self::default()
}
pub fn action(mut self, action: impl Into<String>) -> Self {
self.action = action.into();
self
}
pub fn actor_attr(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
self.actor_attrs.insert(key.into(), value.into());
self
}
pub fn resource_attr(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
self.resource_attrs.insert(key.into(), value.into());
self
}
pub fn environment_attr(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
self.environment_attrs.insert(key.into(), value.into());
self
}
pub fn action_name(&self) -> &str {
&self.action
}
pub(crate) fn lookup(&self, namespace: &str, key: Option<&str>) -> Option<&str> {
match namespace {
"actor" => key.and_then(|k| self.actor_attrs.get(k)).map(String::as_str),
"resource" => key
.and_then(|k| self.resource_attrs.get(k))
.map(String::as_str),
"environment" => key
.and_then(|k| self.environment_attrs.get(k))
.map(String::as_str),
"action" => {
if let Some("name") | Some("id") = key {
Some(self.action.as_str())
} else if key.is_none() {
Some(self.action.as_str())
} else {
None
}
}
_ => None,
}
}
}