Skip to main content

rlnc_simdx/
error.rs

1//! Error types for the `rlnc-simdx` crate.
2
3/// Errors returned by RLNC operations.
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub enum RlncError {
6    /// `generation_size` or `symbol_size` was zero.
7    InvalidParameters,
8    /// A coded packet had wrong coefficient or payload length.
9    PacketSizeMismatch {
10        /// Expected coefficient vector length (`generation_size`).
11        expected_coeffs: usize,
12        /// Actual coefficient vector length received.
13        got_coeffs: usize,
14        /// Expected payload length (`symbol_size`).
15        expected_payload: usize,
16        /// Actual payload length received.
17        got_payload: usize,
18    },
19    /// The source slice count does not match `generation_size`.
20    SourceCountMismatch {
21        /// Expected number of source symbols.
22        expected: usize,
23        /// Actual number of slices provided.
24        got: usize,
25    },
26    /// A source symbol had the wrong byte length.
27    SourceSizeMismatch {
28        /// Expected bytes per symbol.
29        expected: usize,
30        /// Actual slice length.
31        got: usize,
32    },
33    /// Systematic index out of range.
34    IndexOutOfRange {
35        /// Requested systematic symbol index.
36        index: usize,
37        /// Exclusive upper bound (`generation_size`).
38        max: usize,
39    },
40}
41
42impl core::fmt::Display for RlncError {
43    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
44        match self {
45            Self::InvalidParameters => {
46                write!(f, "generation_size and symbol_size must both be > 0")
47            }
48            Self::PacketSizeMismatch {
49                expected_coeffs,
50                got_coeffs,
51                expected_payload,
52                got_payload,
53            } => write!(
54                f,
55                "packet size mismatch: expected ({expected_coeffs} coeffs, {expected_payload} payload), got ({got_coeffs}, {got_payload})"
56            ),
57            Self::SourceCountMismatch { expected, got } => {
58                write!(f, "expected {expected} source symbols, got {got}")
59            }
60            Self::SourceSizeMismatch { expected, got } => {
61                write!(
62                    f,
63                    "source symbol size mismatch: expected {expected} bytes, got {got}"
64                )
65            }
66            Self::IndexOutOfRange { index, max } => {
67                write!(f, "systematic index {index} out of range [0, {max})")
68            }
69        }
70    }
71}
72
73#[cfg(feature = "std")]
74impl std::error::Error for RlncError {}
75
76#[cfg(test)]
77mod tests {
78    use super::*;
79
80    #[test]
81    fn display_variants_non_empty() {
82        let samples = [
83            RlncError::InvalidParameters,
84            RlncError::PacketSizeMismatch {
85                expected_coeffs: 4,
86                got_coeffs: 2,
87                expected_payload: 8,
88                got_payload: 1,
89            },
90            RlncError::SourceCountMismatch {
91                expected: 4,
92                got: 3,
93            },
94            RlncError::SourceSizeMismatch {
95                expected: 16,
96                got: 8,
97            },
98            RlncError::IndexOutOfRange { index: 5, max: 4 },
99        ];
100        for e in samples {
101            let s = format!("{e}");
102            assert!(!s.is_empty(), "empty Display for {e:?}");
103        }
104    }
105}