use std::collections::HashMap;
pub struct Request<'a> {
pub token: &'a dyn Token,
pub target: &'a dyn Target,
}
impl<'a> Request<'a> {
pub fn new(token: &'a dyn Token) -> Self {
Request { token, target: &() }
}
pub fn with_target(mut self, target: &'a dyn Target) -> Self {
self.target = target;
self
}
}
pub trait Token {
#[allow(clippy::needless_lifetimes)] fn get_api_attribute<'k>(&self, name: &'k str) -> Option<&str>;
fn has_role(&self, role_name: &str) -> bool;
}
#[cfg(test)]
pub(crate) mod test {
use std::collections::HashMap;
pub struct Token {
pub roles: Vec<String>,
pub api_attrs: HashMap<String, String>,
}
impl super::Token for Token {
#[allow(clippy::needless_lifetimes)] fn get_api_attribute<'k>(&self, name: &'k str) -> Option<&str> {
self.api_attrs.get(name).map(|x| &**x)
}
fn has_role(&self, role_name: &str) -> bool {
self.roles.iter().any(|n| n == role_name)
}
}
}
pub trait Target {
#[allow(clippy::needless_lifetimes)] fn get_attribute<'n>(&self, name: &'n str) -> Option<&str>;
}
impl Target for () {
#[allow(clippy::needless_lifetimes)] fn get_attribute<'n>(&self, _name: &'n str) -> Option<&str> {
None
}
}
impl Target for HashMap<String, String> {
#[allow(clippy::needless_lifetimes)] fn get_attribute<'n>(&self, name: &'n str) -> Option<&str> {
self.get(name).map(|s| s.as_ref())
}
}
pub(crate) fn resolve_target_attr_refs<'r, 'i: 'r, 't: 'r>(
input: &'i str,
target: &'t dyn Target,
) -> Option<&'r str> {
let Some(stripped) = input.strip_prefix("%(") else {
return Some(input);
};
let Some(attr_name) = stripped.strip_suffix(")s") else {
return Some(input);
};
target.get_attribute(attr_name)
}