Skip to main content

net_wire/kcp/
error.rs

1//! KCP segment construction and parsing errors.
2
3use core::fmt;
4
5/// Failure to construct one KCP segment in caller-provided storage.
6#[derive(Clone, Copy, Debug, Eq, PartialEq)]
7pub enum KcpSegmentBuildError {
8    /// The payload length cannot be represented in KCP's `u32` length field.
9    PayloadLengthTooLarge {
10        /// Requested payload byte length.
11        length: usize,
12    },
13    /// Adding the fixed header length and payload length overflows `usize`.
14    LengthOverflow {
15        /// Fixed header byte length.
16        header_length: usize,
17        /// Requested payload byte length.
18        payload_length: usize,
19    },
20    /// The destination buffer cannot hold the complete segment.
21    BufferTooShort {
22        /// Complete segment byte length required.
23        required: usize,
24        /// Bytes available in the destination buffer.
25        available: usize,
26    },
27}
28
29impl fmt::Display for KcpSegmentBuildError {
30    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31        match self {
32            Self::PayloadLengthTooLarge { length } => {
33                write!(f, "KCP payload length {length} exceeds u32::MAX")
34            }
35            Self::LengthOverflow {
36                header_length,
37                payload_length,
38            } => write!(
39                f,
40                "KCP segment length overflows: header {header_length} plus payload {payload_length}"
41            ),
42            Self::BufferTooShort {
43                required,
44                available,
45            } => write!(
46                f,
47                "KCP buffer is too short: need {required} bytes, have {available}"
48            ),
49        }
50    }
51}
52
53impl core::error::Error for KcpSegmentBuildError {}
54
55/// Failure to parse one KCP segment.
56#[derive(Clone, Copy, Debug, Eq, PartialEq)]
57pub enum KcpSegmentParseError {
58    /// The input does not contain KCP's complete fixed-size header.
59    HeaderTruncated {
60        /// Required header byte length.
61        required: usize,
62        /// Bytes available in the input.
63        available: usize,
64    },
65    /// The encoded payload length cannot be represented on this target.
66    PayloadLengthNotRepresentable {
67        /// Encoded little-endian payload length.
68        value: u32,
69    },
70    /// Adding the fixed header length and encoded payload length overflows `usize`.
71    LengthOverflow {
72        /// Fixed header byte length.
73        header_length: usize,
74        /// Decoded payload byte length.
75        payload_length: usize,
76    },
77    /// The input does not contain the complete encoded payload.
78    PayloadTruncated {
79        /// Complete segment byte length required by the header.
80        required: usize,
81        /// Bytes available in the input.
82        available: usize,
83    },
84}
85
86impl fmt::Display for KcpSegmentParseError {
87    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88        match self {
89            Self::HeaderTruncated {
90                required,
91                available,
92            } => write!(
93                f,
94                "KCP segment header is truncated: need {required} bytes, have {available}"
95            ),
96            Self::PayloadLengthNotRepresentable { value } => write!(
97                f,
98                "KCP segment payload length {value} cannot be represented on this target"
99            ),
100            Self::LengthOverflow {
101                header_length,
102                payload_length,
103            } => write!(
104                f,
105                "KCP segment length overflows: header {header_length} plus payload {payload_length}"
106            ),
107            Self::PayloadTruncated {
108                required,
109                available,
110            } => write!(
111                f,
112                "KCP segment payload is truncated: need {required} bytes, have {available}"
113            ),
114        }
115    }
116}
117
118impl core::error::Error for KcpSegmentParseError {}
119
120/// Failure to validate a complete concatenated KCP segment sequence.
121#[derive(Clone, Copy, Debug, Eq, PartialEq)]
122pub enum KcpSegmentsParseError {
123    /// The supplied sequence contains no segments.
124    EmptySequence,
125    /// A segment cannot be parsed at the indicated absolute byte offset.
126    Segment {
127        /// Absolute byte offset from the sequence start.
128        offset: usize,
129        /// Exact failure while parsing the segment.
130        error: KcpSegmentParseError,
131    },
132}
133
134impl fmt::Display for KcpSegmentsParseError {
135    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
136        match self {
137            Self::EmptySequence => f.write_str("KCP segment sequence is empty"),
138            Self::Segment { offset, error } => {
139                write!(
140                    f,
141                    "KCP segment at offset {offset} cannot be parsed: {error}"
142                )
143            }
144        }
145    }
146}
147
148impl core::error::Error for KcpSegmentsParseError {
149    fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
150        match self {
151            Self::Segment { error, .. } => Some(error),
152            Self::EmptySequence => None,
153        }
154    }
155}