use core::fmt;
use std::error;
use crate::hpke::HpkeError;
use crate::ohttp::{DirectoryResponseError, OhttpEncapsulationError};
use crate::receive::error::Error;
use crate::receive::ProtocolError;
use crate::time::Time;
#[derive(Debug)]
pub struct SessionError(pub(super) InternalSessionError);
impl From<InternalSessionError> for SessionError {
fn from(value: InternalSessionError) -> Self { SessionError(value) }
}
impl From<InternalSessionError> for Error {
fn from(e: InternalSessionError) -> Self { Error::Protocol(ProtocolError::V2(e.into())) }
}
#[derive(Debug)]
pub(crate) enum InternalSessionError {
ParseUrl(crate::into_url::Error),
Expired(Time),
OhttpEncapsulation(OhttpEncapsulationError),
Hpke(HpkeError),
DirectoryResponse(DirectoryResponseError),
}
impl From<OhttpEncapsulationError> for Error {
fn from(e: OhttpEncapsulationError) -> Self {
InternalSessionError::OhttpEncapsulation(e).into()
}
}
impl From<HpkeError> for Error {
fn from(e: HpkeError) -> Self { InternalSessionError::Hpke(e).into() }
}
impl fmt::Display for SessionError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use InternalSessionError::*;
match &self.0 {
ParseUrl(e) => write!(f, "URL parsing failed: {e}"),
Expired(expiration) => write!(f, "Session expired at {expiration:?}"),
OhttpEncapsulation(e) => write!(f, "OHTTP Encapsulation Error: {e}"),
Hpke(e) => write!(f, "Hpke decryption failed: {e}"),
DirectoryResponse(e) => write!(f, "Directory response error: {e}"),
}
}
}
impl error::Error for SessionError {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
use InternalSessionError::*;
match &self.0 {
ParseUrl(e) => Some(e),
Expired(_) => None,
OhttpEncapsulation(e) => Some(e),
Hpke(e) => Some(e),
DirectoryResponse(e) => Some(e),
}
}
}