1use thiserror::Error;
4
5pub type Result<T> = std::result::Result<T, Error>;
7
8#[derive(Error, Debug)]
10pub enum Error {
11 #[error("invalid magic byte: expected 0x53, got 0x{0:02x}")]
13 InvalidMagic(u8),
14
15 #[error("payload too large: {0} bytes (max 65535)")]
17 PayloadTooLarge(usize),
18
19 #[error("buffer too small: need {needed} bytes, have {have}")]
21 BufferTooSmall { needed: usize, have: usize },
22
23 #[error("encode error: {0}")]
25 EncodeError(String),
26
27 #[error("decode error: {0}")]
29 DecodeError(String),
30
31 #[error("unknown message type: 0x{0:02x}")]
33 UnknownMessageType(u8),
34
35 #[error("unknown signal type: {0}")]
37 UnknownSignalType(String),
38
39 #[error("invalid address: {0}")]
41 InvalidAddress(String),
42
43 #[error("invalid pattern: {0}")]
45 InvalidPattern(String),
46
47 #[error("state conflict: revision {expected} expected, got {actual}")]
49 RevisionConflict { expected: u64, actual: u64 },
50
51 #[error("lock held by {holder}")]
53 LockHeld { holder: String },
54
55 #[error("permission denied: {0}")]
57 PermissionDenied(String),
58
59 #[error("connection error: {0}")]
61 ConnectionError(String),
62
63 #[error("operation timed out")]
65 Timeout,
66
67 #[error("protocol error: {0}")]
69 Protocol(String),
70}
71
72impl From<rmp_serde::encode::Error> for Error {
73 fn from(e: rmp_serde::encode::Error) -> Self {
74 Error::EncodeError(e.to_string())
75 }
76}
77
78impl From<rmp_serde::decode::Error> for Error {
79 fn from(e: rmp_serde::decode::Error) -> Self {
80 Error::DecodeError(e.to_string())
81 }
82}
83
84#[derive(Debug, Clone, Copy, PartialEq, Eq)]
86#[repr(u16)]
87pub enum ErrorCode {
88 InvalidFrame = 100,
90 InvalidMessage = 101,
91 UnsupportedVersion = 102,
92
93 InvalidAddress = 200,
95 AddressNotFound = 201,
96 PatternError = 202,
97
98 Unauthorized = 300,
100 Forbidden = 301,
101 TokenExpired = 302,
102
103 RevisionConflict = 400,
105 LockHeld = 401,
106 InvalidValue = 402,
107
108 InternalError = 500,
110 ServiceUnavailable = 501,
111 Timeout = 502,
112}
113
114impl ErrorCode {
115 pub fn from_u16(code: u16) -> Option<Self> {
116 match code {
117 100 => Some(ErrorCode::InvalidFrame),
118 101 => Some(ErrorCode::InvalidMessage),
119 102 => Some(ErrorCode::UnsupportedVersion),
120 200 => Some(ErrorCode::InvalidAddress),
121 201 => Some(ErrorCode::AddressNotFound),
122 202 => Some(ErrorCode::PatternError),
123 300 => Some(ErrorCode::Unauthorized),
124 301 => Some(ErrorCode::Forbidden),
125 302 => Some(ErrorCode::TokenExpired),
126 400 => Some(ErrorCode::RevisionConflict),
127 401 => Some(ErrorCode::LockHeld),
128 402 => Some(ErrorCode::InvalidValue),
129 500 => Some(ErrorCode::InternalError),
130 501 => Some(ErrorCode::ServiceUnavailable),
131 502 => Some(ErrorCode::Timeout),
132 _ => None,
133 }
134 }
135}