use super::UntrustedValue;
use untrusted_value_derive_internals::{SanitizeValue, SanitizeWith};
pub enum MaybeUntrusted<Insecure, Trusted = Insecure> {
Ok(Trusted),
Untrusted(UntrustedValue<Insecure>),
}
impl<Insecure> MaybeUntrusted<Insecure> {
pub fn use_untrusted_value(self) -> Insecure {
match self {
MaybeUntrusted::Ok(value) => value,
MaybeUntrusted::Untrusted(value) => value.use_untrusted_value(),
}
}
pub fn wrap(value: Insecure, untrusted: bool) -> Self {
if untrusted {
Self::wrap_untrusted(value)
} else {
Self::wrap_ok(value)
}
}
}
impl<Insecure, Trusted> MaybeUntrusted<Insecure, Trusted> {
pub fn is_untrusted(&self) -> bool {
match self {
MaybeUntrusted::Ok(_) => false,
MaybeUntrusted::Untrusted(_) => true,
}
}
pub fn is_ok(&self) -> bool {
!self.is_untrusted()
}
pub fn wrap_untrusted(value: Insecure) -> Self {
MaybeUntrusted::Untrusted(value.into())
}
pub fn wrap_ok(value: Trusted) -> Self {
MaybeUntrusted::Ok(value)
}
}
impl<Insecure, Trusted> SanitizeWith<Insecure, Trusted> for MaybeUntrusted<Insecure, Trusted> {
fn sanitize_with<Sanitizer, Error>(self, sanitizer: Sanitizer) -> Result<Trusted, Error>
where
Sanitizer: FnOnce(Insecure) -> Result<Trusted, Error>,
{
match self {
MaybeUntrusted::Ok(value) => Ok(value),
MaybeUntrusted::Untrusted(value) => value.sanitize_with(sanitizer),
}
}
}
impl<Insecure, Trusted> From<UntrustedValue<Insecure>> for MaybeUntrusted<Insecure, Trusted> {
fn from(value: UntrustedValue<Insecure>) -> Self {
MaybeUntrusted::Untrusted(value)
}
}
#[allow(clippy::expl_impl_clone_on_copy)]
impl<Insecure: Clone, Trusted: Clone> Clone for MaybeUntrusted<Insecure, Trusted> {
fn clone(&self) -> Self {
match self {
MaybeUntrusted::Ok(value) => MaybeUntrusted::Ok(value.clone()),
MaybeUntrusted::Untrusted(value) => MaybeUntrusted::Untrusted(value.clone()),
}
}
}
impl<Insecure: Copy, Trusted: Copy> Copy for MaybeUntrusted<Insecure, Trusted> {}
impl<E, Insecure: SanitizeValue<Insecure, Error = E>> SanitizeValue<Insecure>
for MaybeUntrusted<Insecure>
{
type Error = E;
fn sanitize_value(self) -> Result<Insecure, Self::Error> {
match self {
MaybeUntrusted::Ok(value) => Ok(value),
MaybeUntrusted::Untrusted(value) => value.sanitize_value(),
}
}
}