1use core::fmt;
6
7use zerodds_cdr::{DecodeError, EncodeError};
8
9#[derive(Debug, Clone, PartialEq, Eq)]
11#[non_exhaustive]
12pub enum TypeCodecError {
13 Encode(EncodeError),
15 Decode(DecodeError),
17 UnknownTypeKind {
19 kind: u8,
21 },
22}
23
24impl fmt::Display for TypeCodecError {
25 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26 match self {
27 Self::Encode(e) => write!(f, "type codec encode error: {e}"),
28 Self::Decode(e) => write!(f, "type codec decode error: {e}"),
29 Self::UnknownTypeKind { kind } => {
30 write!(f, "unknown TypeKind discriminator 0x{kind:02x}")
31 }
32 }
33 }
34}
35
36#[cfg(feature = "std")]
37extern crate std;
38
39#[cfg(feature = "std")]
40impl std::error::Error for TypeCodecError {}
41
42impl From<EncodeError> for TypeCodecError {
43 fn from(e: EncodeError) -> Self {
44 Self::Encode(e)
45 }
46}
47
48impl From<DecodeError> for TypeCodecError {
49 fn from(e: DecodeError) -> Self {
50 Self::Decode(e)
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57 use alloc::string::ToString;
58
59 #[test]
60 fn display_unknown_type_kind_hex_formatted() {
61 let e = TypeCodecError::UnknownTypeKind { kind: 0xAB };
62 let s = e.to_string();
63 assert!(s.contains("0xab") || s.contains("0xAB"), "got: {s}");
64 }
65
66 #[test]
67 fn from_encode_and_decode_error() {
68 let enc = EncodeError::ValueOutOfRange { message: "test" };
69 let e1 = TypeCodecError::from(enc);
70 assert!(matches!(e1, TypeCodecError::Encode(_)));
71
72 let dec = DecodeError::UnexpectedEof {
73 needed: 4,
74 offset: 0,
75 };
76 let e2 = TypeCodecError::from(dec);
77 assert!(matches!(e2, TypeCodecError::Decode(_)));
78 }
79
80 #[test]
81 fn display_encode_decode_variants_dont_panic() {
82 let _ = TypeCodecError::Encode(EncodeError::ValueOutOfRange { message: "x" }).to_string();
83 let _ = TypeCodecError::Decode(DecodeError::UnexpectedEof {
84 needed: 1,
85 offset: 2,
86 })
87 .to_string();
88 }
89}