1// Copyright (c) 2023 Huawei Device Co., Ltd.
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6//     http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14//! Errors that may occur in this crate.
15//!
16//! This module provide unified encapsulation of HTTP errors.
17//!
18//! [`HttpError`] encapsulates error information related to all http protocols
19//! including `UriError`, `H1Error`, etc.
20//!
21//! [`HttpError`]: HttpError
22
23use core::fmt::{Debug, Display, Formatter};
24use std::convert::Infallible;
25use std::error::Error;
26
27#[cfg(feature = "http1_1")]
28use crate::h1::H1Error;
29#[cfg(feature = "http2")]
30use crate::h2::H2Error;
31#[cfg(feature = "http3")]
32use crate::h3::H3Error;
33use crate::request::uri::InvalidUri;
34
35/// Errors that may occur when using this crate.
36#[derive(Debug, Eq, PartialEq)]
37pub struct HttpError {
38    kind: ErrorKind,
39}
40
41impl From<ErrorKind> for HttpError {
42    fn from(kind: ErrorKind) -> Self {
43        HttpError { kind }
44    }
45}
46
47impl From<InvalidUri> for HttpError {
48    fn from(err: InvalidUri) -> Self {
49        ErrorKind::Uri(err).into()
50    }
51}
52
53#[cfg(feature = "http2")]
54impl From<H2Error> for HttpError {
55    fn from(err: H2Error) -> Self {
56        ErrorKind::H2(err).into()
57    }
58}
59
60#[cfg(feature = "http3")]
61impl From<H3Error> for HttpError {
62    fn from(err: H3Error) -> Self {
63        ErrorKind::H3(err).into()
64    }
65}
66
67impl From<Infallible> for HttpError {
68    fn from(_value: Infallible) -> Self {
69        unreachable!()
70    }
71}
72
73impl Display for HttpError {
74    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
75        Debug::fmt(self, f)
76    }
77}
78
79impl Error for HttpError {}
80
81#[derive(Debug, Eq, PartialEq)]
82pub(crate) enum ErrorKind {
83    /// An invalid input parameter was passed to a method of this crate.
84    InvalidInput,
85
86    /// Errors related to URIs.
87    Uri(InvalidUri),
88
89    /// Errors related to `HTTP/1`.
90    #[cfg(feature = "http1_1")]
91    H1(H1Error),
92
93    /// Errors related to `HTTP/2`.
94    #[cfg(feature = "http2")]
95    H2(H2Error),
96
97    /// Errors related to `HTTP/2`.
98    #[cfg(feature = "http3")]
99    H3(H3Error),
100}
101