1use core::fmt;
7
8use crate::qpack::field::section::decode::{
9 QpackFieldSectionDecodeError, QpackFieldSectionDecodeOutcome, QpackFieldSectionDecoder,
10 QpackFieldSectionOutput,
11};
12use crate::qpack::table::dynamic::QpackDynamicTable;
13
14use super::frame::{Http3Headers, Http3PushPromise};
15
16#[derive(Clone, Copy, Debug, Eq, PartialEq)]
22pub enum Http3QpackFieldSectionError {
23 DecompressionFailed(QpackFieldSectionDecodeError),
25 OutputProvisioning(QpackFieldSectionDecodeError),
27}
28
29impl Http3QpackFieldSectionError {
30 pub const fn error_code(self) -> Option<super::codepoints::Http3ErrorCode> {
32 match self {
33 Self::DecompressionFailed(_) => {
34 Some(super::codepoints::Http3ErrorCode::QPACK_DECOMPRESSION_FAILED)
35 }
36 Self::OutputProvisioning(_) => None,
37 }
38 }
39}
40
41impl From<QpackFieldSectionDecodeError> for Http3QpackFieldSectionError {
42 fn from(error: QpackFieldSectionDecodeError) -> Self {
43 match error.is_decompression_failed() {
44 true => Self::DecompressionFailed(error),
45 false => Self::OutputProvisioning(error),
46 }
47 }
48}
49
50impl fmt::Display for Http3QpackFieldSectionError {
51 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
52 match self {
53 Self::DecompressionFailed(error) => {
54 write!(f, "HTTP/3 QPACK decompression failed: {error}")
55 }
56 Self::OutputProvisioning(error) => {
57 write!(
58 f,
59 "HTTP/3 QPACK output provisioning failed locally: {error}"
60 )
61 }
62 }
63 }
64}
65
66impl core::error::Error for Http3QpackFieldSectionError {
67 fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
68 match self {
69 Self::DecompressionFailed(error) | Self::OutputProvisioning(error) => Some(error),
70 }
71 }
72}
73
74impl Http3Headers<'_> {
75 pub fn decode_field_section<'output>(
82 &self,
83 decoder: &QpackFieldSectionDecoder,
84 table: &QpackDynamicTable<'_, '_>,
85 output: &'output mut QpackFieldSectionOutput<'_, '_>,
86 ) -> Result<QpackFieldSectionDecodeOutcome<'output>, Http3QpackFieldSectionError> {
87 decode_field_section(self.encoded_field_section(), decoder, table, output)
88 }
89}
90
91impl Http3PushPromise<'_> {
92 pub fn decode_field_section<'output>(
99 &self,
100 decoder: &QpackFieldSectionDecoder,
101 table: &QpackDynamicTable<'_, '_>,
102 output: &'output mut QpackFieldSectionOutput<'_, '_>,
103 ) -> Result<QpackFieldSectionDecodeOutcome<'output>, Http3QpackFieldSectionError> {
104 decode_field_section(self.encoded_field_section(), decoder, table, output)
105 }
106}
107
108fn decode_field_section<'output>(
109 encoded_field_section: &[u8],
110 decoder: &QpackFieldSectionDecoder,
111 table: &QpackDynamicTable<'_, '_>,
112 output: &'output mut QpackFieldSectionOutput<'_, '_>,
113) -> Result<QpackFieldSectionDecodeOutcome<'output>, Http3QpackFieldSectionError> {
114 decoder
115 .decode(encoded_field_section, table, output)
116 .map_err(Http3QpackFieldSectionError::from)
117}