use secrecy::{ExposeSecret, SecretString};
use serde_json::{Map, Value};
use std::sync::Arc;
use std::time::Instant;
static HTTP_HEADER_NAME_ATTRIBUTE: &str = "http.header_name";
static HTTP_HEADER_SCHEME_ATTRIBUTE: &str = "http.header_scheme";
#[derive(Clone, Debug)]
pub struct ApiKey {
value: Arc<SecretString>,
attributes: Option<Arc<Map<String, Value>>>,
expires_on: Option<Instant>,
}
impl ApiKey {
#[must_use]
pub fn new(value: impl Into<SecretString>) -> Self {
Self {
value: Arc::new(value.into()),
attributes: None,
expires_on: None,
}
}
#[must_use]
pub fn with_attributes(mut self, attributes: Map<String, Value>) -> Self {
self.attributes = Some(Arc::new(attributes));
self
}
#[must_use]
pub const fn with_expiry(mut self, expires_on: Instant) -> Self {
self.expires_on = Some(expires_on);
self
}
#[must_use]
pub fn with_http_header_name_attribute(mut self, header_name: &str) -> Self {
let mut attributes = self
.attributes
.map(Arc::unwrap_or_clone)
.unwrap_or_default();
attributes[HTTP_HEADER_NAME_ATTRIBUTE] = Value::String(header_name.into());
self.attributes = Some(Arc::new(attributes));
self
}
#[must_use]
pub fn with_http_header_scheme_attribute(mut self, header_scheme: &str) -> Self {
let mut attributes = self
.attributes
.map(Arc::unwrap_or_clone)
.unwrap_or_default();
attributes[HTTP_HEADER_SCHEME_ATTRIBUTE] = Value::String(header_scheme.into());
self.attributes = Some(Arc::new(attributes));
self
}
#[must_use]
pub fn expose_value(&self) -> &str {
self.value.expose_secret()
}
#[must_use]
pub fn get_attributes(&self) -> Option<&Map<String, Value>> {
self.attributes.as_deref()
}
#[must_use]
pub const fn get_expires_on(&self) -> Option<Instant> {
self.expires_on
}
#[must_use]
pub fn get_http_header_name_attribute(&self) -> Option<&str> {
if let Some(header_value) = self
.attributes
.as_ref()
.and_then(|v| v.get(HTTP_HEADER_NAME_ATTRIBUTE))
&& let Value::String(header_value) = header_value
{
return Some(header_value.as_str());
}
None
}
#[must_use]
pub fn get_http_header_scheme_attribute(&self) -> Option<&str> {
if let Some(scheme_value) = self
.attributes
.as_ref()
.and_then(|v| v.get(HTTP_HEADER_SCHEME_ATTRIBUTE))
&& let Value::String(scheme_value) = scheme_value
{
return Some(scheme_value.as_str());
}
None
}
}