use core::fmt;
use crate::qpack::field::section::decode::{
QpackFieldSectionDecodeError, QpackFieldSectionDecodeOutcome, QpackFieldSectionDecoder,
QpackFieldSectionOutput,
};
use crate::qpack::table::dynamic::QpackDynamicTable;
use super::frame::{Http3Headers, Http3PushPromise};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Http3QpackFieldSectionError {
DecompressionFailed(QpackFieldSectionDecodeError),
OutputProvisioning(QpackFieldSectionDecodeError),
}
impl Http3QpackFieldSectionError {
pub const fn error_code(self) -> Option<super::codepoints::Http3ErrorCode> {
match self {
Self::DecompressionFailed(_) => {
Some(super::codepoints::Http3ErrorCode::QPACK_DECOMPRESSION_FAILED)
}
Self::OutputProvisioning(_) => None,
}
}
}
impl From<QpackFieldSectionDecodeError> for Http3QpackFieldSectionError {
fn from(error: QpackFieldSectionDecodeError) -> Self {
match error.is_decompression_failed() {
true => Self::DecompressionFailed(error),
false => Self::OutputProvisioning(error),
}
}
}
impl fmt::Display for Http3QpackFieldSectionError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::DecompressionFailed(error) => {
write!(f, "HTTP/3 QPACK decompression failed: {error}")
}
Self::OutputProvisioning(error) => {
write!(
f,
"HTTP/3 QPACK output provisioning failed locally: {error}"
)
}
}
}
}
impl core::error::Error for Http3QpackFieldSectionError {
fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
match self {
Self::DecompressionFailed(error) | Self::OutputProvisioning(error) => Some(error),
}
}
}
impl Http3Headers<'_> {
pub fn decode_field_section<'output>(
&self,
decoder: &QpackFieldSectionDecoder,
table: &QpackDynamicTable<'_, '_>,
output: &'output mut QpackFieldSectionOutput<'_, '_>,
) -> Result<QpackFieldSectionDecodeOutcome<'output>, Http3QpackFieldSectionError> {
decode_field_section(self.encoded_field_section(), decoder, table, output)
}
}
impl Http3PushPromise<'_> {
pub fn decode_field_section<'output>(
&self,
decoder: &QpackFieldSectionDecoder,
table: &QpackDynamicTable<'_, '_>,
output: &'output mut QpackFieldSectionOutput<'_, '_>,
) -> Result<QpackFieldSectionDecodeOutcome<'output>, Http3QpackFieldSectionError> {
decode_field_section(self.encoded_field_section(), decoder, table, output)
}
}
fn decode_field_section<'output>(
encoded_field_section: &[u8],
decoder: &QpackFieldSectionDecoder,
table: &QpackDynamicTable<'_, '_>,
output: &'output mut QpackFieldSectionOutput<'_, '_>,
) -> Result<QpackFieldSectionDecodeOutcome<'output>, Http3QpackFieldSectionError> {
decoder
.decode(encoded_field_section, table, output)
.map_err(Http3QpackFieldSectionError::from)
}