use std::marker::PhantomData;
use crate::{RedactableWithFormatter, RedactionPolicy, redaction::PolicyMapper};
use super::{
field::{
PolicyApplicableRefForFormatting, PolicyApplicableRefForGeneratedFormatting, PolicyFieldRef,
},
kinds::{
GeneratedPolicyKindDebugFormatting, GeneratedPolicyKindDisplayFormatting,
PolicyKindDebugFormatting, PolicyKindDisplayFormatting,
},
};
#[doc(hidden)]
pub trait PolicyFormattingDispatch {
type Output<P: RedactionPolicy>;
fn redactable_policy_formatting<P: RedactionPolicy>(self) -> Self::Output<P>;
}
#[doc(hidden)]
pub struct LegacyPolicyFormattingRef<'a, P, T: ?Sized> {
value: &'a T,
policy: PhantomData<P>,
}
#[doc(hidden)]
pub struct ExplicitLegacyPolicyFormattingRef<'a, P, T: ?Sized> {
value: &'a T,
policy: PhantomData<P>,
}
#[doc(hidden)]
pub fn legacy_policy_formatting_ref<P, T: ?Sized>(
value: &T,
) -> ExplicitLegacyPolicyFormattingRef<'_, P, T> {
ExplicitLegacyPolicyFormattingRef {
value,
policy: PhantomData,
}
}
impl<P, T> std::fmt::Display for ExplicitLegacyPolicyFormattingRef<'_, P, T>
where
P: RedactionPolicy,
T: PolicyFieldRef<P> + ?Sized,
<T as PolicyFieldRef<P>>::Output: RedactableWithFormatter,
{
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.value
.apply_field_ref(&PolicyMapper)
.fmt_redacted(formatter)
}
}
impl<P, T> std::fmt::Debug for ExplicitLegacyPolicyFormattingRef<'_, P, T>
where
P: RedactionPolicy,
T: PolicyFieldRef<P> + ?Sized,
<T as PolicyFieldRef<P>>::Output: std::fmt::Debug,
{
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Debug::fmt(&self.value.apply_field_ref(&PolicyMapper), formatter)
}
}
impl<P, T> std::fmt::Display for LegacyPolicyFormattingRef<'_, P, T>
where
P: RedactionPolicy,
P::Kind: PolicyKindDisplayFormatting<P, T>,
T: ?Sized,
{
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
<P::Kind as PolicyKindDisplayFormatting<P, T>>::fmt_display(self.value, formatter)
}
}
impl<P, T> std::fmt::Debug for LegacyPolicyFormattingRef<'_, P, T>
where
P: RedactionPolicy,
P::Kind: PolicyKindDebugFormatting<P, T>,
T: ?Sized,
{
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
<P::Kind as PolicyKindDebugFormatting<P, T>>::fmt_debug(self.value, formatter)
}
}
#[doc(hidden)]
pub struct PolicyFormattingProbe<'a, T: ?Sized> {
value: &'a T,
}
#[doc(hidden)]
pub fn policy_formatting_probe<T: ?Sized>(value: &T) -> PolicyFormattingProbe<'_, T> {
PolicyFormattingProbe { value }
}
impl<'a, T> PolicyFormattingDispatch for PolicyFormattingProbe<'a, T>
where
T: PolicyApplicableRefForGeneratedFormatting + ?Sized,
{
type Output<P: RedactionPolicy> = GeneratedPolicyFormattingRef<'a, P, T>;
fn redactable_policy_formatting<P: RedactionPolicy>(self) -> Self::Output<P> {
GeneratedPolicyFormattingRef {
value: self.value,
policy: PhantomData,
}
}
}
impl<'a, T> PolicyFormattingDispatch for &PolicyFormattingProbe<'a, T>
where
T: PolicyApplicableRefForFormatting + ?Sized,
{
type Output<P: RedactionPolicy> = LegacyPolicyFormattingRef<'a, P, T>;
fn redactable_policy_formatting<P: RedactionPolicy>(self) -> Self::Output<P> {
LegacyPolicyFormattingRef {
value: self.value,
policy: PhantomData,
}
}
}
#[doc(hidden)]
pub struct PolicyFormattingRef<'a, P, T: ?Sized> {
value: &'a T,
policy: PhantomData<P>,
}
#[doc(hidden)]
pub fn policy_formatting_ref<P, T: ?Sized>(value: &T) -> PolicyFormattingRef<'_, P, T> {
PolicyFormattingRef {
value,
policy: PhantomData,
}
}
impl<P, T> std::fmt::Display for PolicyFormattingRef<'_, P, T>
where
P: RedactionPolicy,
P::Kind: PolicyKindDisplayFormatting<P, T>,
T: ?Sized,
{
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
<P::Kind as PolicyKindDisplayFormatting<P, T>>::fmt_display(self.value, formatter)
}
}
impl<P, T> std::fmt::Debug for PolicyFormattingRef<'_, P, T>
where
P: RedactionPolicy,
P::Kind: PolicyKindDebugFormatting<P, T>,
T: ?Sized,
{
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
<P::Kind as PolicyKindDebugFormatting<P, T>>::fmt_debug(self.value, formatter)
}
}
#[doc(hidden)]
pub struct GeneratedPolicyFormattingRef<'a, P, T: ?Sized> {
value: &'a T,
policy: PhantomData<P>,
}
impl<P, T> std::fmt::Display for GeneratedPolicyFormattingRef<'_, P, T>
where
P: RedactionPolicy,
P::Kind: GeneratedPolicyKindDisplayFormatting<P, T>,
T: ?Sized,
{
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
<P::Kind as GeneratedPolicyKindDisplayFormatting<P, T>>::fmt_generated_display(
self.value, formatter,
)
}
}
impl<P, T> std::fmt::Debug for GeneratedPolicyFormattingRef<'_, P, T>
where
P: RedactionPolicy,
P::Kind: GeneratedPolicyKindDebugFormatting<P, T>,
T: ?Sized,
{
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
<P::Kind as GeneratedPolicyKindDebugFormatting<P, T>>::fmt_generated_debug(
self.value, formatter,
)
}
}