use std::fmt;
use sip_uri::Redaction;
use crate::traits::sealed;
pub trait Redact: sealed::Sealed {
fn redacted<'a>(&'a self, how: &'a HeaderRedaction) -> impl fmt::Display + 'a;
}
const IDENTITY_PARAMS: &[&str] = &["+sip.instance", "pub-gruu", "temp-gruu"];
const VIA_ADDRESS_PARAMS: &[&str] = &["received", "maddr"];
#[derive(Debug, Clone, PartialEq, Eq, Default)]
#[non_exhaustive]
pub struct HeaderRedaction {
uri: Redaction,
show_instance: bool,
show_location: bool,
show_via_addresses: bool,
}
impl HeaderRedaction {
pub fn new(uri: Redaction) -> Self {
HeaderRedaction {
uri,
..HeaderRedaction::default()
}
}
pub fn uri(&self) -> &Redaction {
&self.uri
}
pub fn show_instance(mut self) -> Self {
self.show_instance = true;
self
}
pub fn show_location(mut self) -> Self {
self.show_location = true;
self
}
pub fn show_via_addresses(mut self) -> Self {
self.show_via_addresses = true;
self
}
pub(crate) fn masks_location(&self) -> bool {
!self.show_location
}
pub(crate) fn masks_via_host(&self) -> bool {
!self.show_via_addresses
}
pub(crate) fn masks_param(&self, name: &str) -> bool {
(!self.show_instance && IDENTITY_PARAMS.contains(&name))
|| self
.uri
.masks_param(name)
}
pub(crate) fn masks_via_param(&self, name: &str) -> bool {
(self.masks_via_host() && VIA_ADDRESS_PARAMS.contains(&name)) || self.masks_param(name)
}
}
impl From<Redaction> for HeaderRedaction {
fn from(uri: Redaction) -> Self {
HeaderRedaction::new(uri)
}
}
pub(crate) struct RedactedList<'a, T>(pub(crate) &'a [T], pub(crate) &'a HeaderRedaction);
impl<T: Redact> fmt::Display for RedactedList<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for (i, entry) in self
.0
.iter()
.enumerate()
{
if i > 0 {
f.write_str(", ")?;
}
write!(f, "{}", entry.redacted(self.1))?;
}
Ok(())
}
}