1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
//! Error-handling utilities.

pub use crate::backend::BackendError;
pub use anyhow::{anyhow, bail, ensure, Error};
use std::fmt;

/// Enum describing what kind of buffer had insufficient size, in a [`BufferSizeError`].
#[non_exhaustive]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum BufferKind {
    /// The too-small buffer is for holding a header name.
    HeaderName,
    /// The too-small buffer is for holding a header value.
    HeaderValue,
    /// The too-small buffer is for holding an HTTP method.
    HttpMethod,
    /// The too-small buffer is for holding a URL.
    Url,
}

impl fmt::Display for BufferKind {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            BufferKind::HttpMethod => {
                write!(f, "HTTP method")
            }
            BufferKind::HeaderName => {
                write!(f, "header name")
            }
            BufferKind::HeaderValue => {
                write!(f, "header value")
            }
            BufferKind::Url => {
                write!(f, "URL")
            }
        }
    }
}

/// Insufficient buffer size error.
///
/// This is returned by methods like
/// [`RequestHandle::get_header_names()`][`crate::handle::RequestHandle::get_header_names()`] if a
/// value was larger than the provided maximum size.
///
/// If you get such an error, you can try the same call again with a larger buffer.
#[derive(Copy, Clone, Debug, PartialEq, Eq, thiserror::Error)]
#[error("insufficient buffer size {buf_size} for buffer '{buffer_kind}'; value requires {needed_buf_size} bytes")]
pub struct BufferSizeError {
    /// The attempted buffer size.
    ///
    /// This is to help make nicer error messages.
    pub buf_size: usize,
    /// The buffer size that was required.
    ///
    /// Trying an operation again with a buffer at least this big may succeed where a previous call
    /// failed. However, it is not guaranteed to succeed, for example if there is an even larger
    /// value later in the list than the first value that was too large.
    pub needed_buf_size: usize,
    /// The buffer kind whose size was insufficient.
    pub buffer_kind: BufferKind,
}

impl BufferSizeError {
    /// Create a new [`BufferSizeError`].
    pub(crate) fn new(buf_size: usize, needed_buf_size: usize, buffer_kind: BufferKind) -> Self {
        Self {
            buf_size,
            needed_buf_size,
            buffer_kind,
        }
    }

    /// Create a new [`BufferSizeError`] for a failure to handle a header name.
    pub(crate) fn header_name(buf_size: usize, needed_buf_size: usize) -> Self {
        Self::new(buf_size, needed_buf_size, BufferKind::HeaderName)
    }

    /// Create a new [`BufferSizeError`] for a failure to handle a header value.
    pub(crate) fn header_value(buf_size: usize, needed_buf_size: usize) -> Self {
        Self::new(buf_size, needed_buf_size, BufferKind::HeaderValue)
    }

    /// Create a new [`BufferSizeError`] for a failure to handle an HTTP method.
    pub(crate) fn http_method(buf_size: usize, needed_buf_size: usize) -> Self {
        Self::new(buf_size, needed_buf_size, BufferKind::HttpMethod)
    }

    /// Create a new [`BufferSizeError`] for a failure to handle a URL.
    pub(crate) fn url(buf_size: usize, needed_buf_size: usize) -> Self {
        Self::new(buf_size, needed_buf_size, BufferKind::Url)
    }
}