reach_core/
error.rs

1// SPDX-FileCopyrightText: 2023—2025 eaon <eaon@posteo.net>
2// SPDX-License-Identifier: EUPL-1.2
3
4use core::fmt::{Formatter, Result};
5use std::array::TryFromSliceError;
6use std::error::Error;
7use std::fmt::Display;
8
9#[cfg(feature = "websocket")]
10use crate::communication::{CommunicableType, Communication};
11
12#[derive(Debug, Default)]
13pub struct DecodeError;
14
15impl Display for DecodeError {
16    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
17        f.write_str("DecodeError")
18    }
19}
20
21impl Error for DecodeError {}
22
23impl From<ed25519_dalek::ed25519::Error> for DecodeError {
24    fn from(_: ed25519_dalek::ed25519::Error) -> Self {
25        Self
26    }
27}
28
29impl From<TryFromSliceError> for DecodeError {
30    fn from(_: TryFromSliceError) -> Self {
31        Self
32    }
33}
34
35impl From<prost::DecodeError> for DecodeError {
36    fn from(_: prost::DecodeError) -> Self {
37        Self
38    }
39}
40
41impl From<chacha20poly1305::Error> for DecodeError {
42    fn from(_: chacha20poly1305::Error) -> Self {
43        Self
44    }
45}
46
47impl From<std::num::TryFromIntError> for DecodeError {
48    fn from(_: std::num::TryFromIntError) -> Self {
49        Self
50    }
51}
52
53impl From<generic_array::LengthError> for DecodeError {
54    fn from(_: generic_array::LengthError) -> Self {
55        Self
56    }
57}
58
59impl From<ecdh_omr::Error> for DecodeError {
60    fn from(_: ecdh_omr::Error) -> Self {
61        Self
62    }
63}
64
65impl From<prost::UnknownEnumValue> for DecodeError {
66    fn from(_: prost::UnknownEnumValue) -> Self {
67        Self
68    }
69}
70
71#[derive(Debug, Default)]
72pub struct EncodeError;
73
74impl Display for EncodeError {
75    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
76        f.write_str("EncodeError")
77    }
78}
79
80impl Error for EncodeError {}
81
82impl From<prost::EncodeError> for EncodeError {
83    fn from(_: prost::EncodeError) -> Self {
84        Self
85    }
86}
87
88impl From<chacha20poly1305::aead::Error> for EncodeError {
89    fn from(_: chacha20poly1305::aead::Error) -> Self {
90        Self
91    }
92}
93
94#[derive(Debug, thiserror::Error)]
95pub enum CryptError {
96    #[error("decryption failed")]
97    DecryptionFailed,
98    #[error("cipher: {0}")]
99    Cipher(chacha20poly1305::Error),
100    #[error("encryption: {0}")]
101    Encryption(#[from] ecdh_omr::Error),
102    #[error("post-decryption decode error: {0}")]
103    PostDecryption(#[from] DecodeError),
104    #[error("authentication failed")]
105    AuthenticationFailed,
106}
107
108impl From<chacha20poly1305::Error> for CryptError {
109    fn from(error: chacha20poly1305::Error) -> Self {
110        CryptError::Cipher(error)
111    }
112}
113
114#[derive(Debug, thiserror::Error)]
115pub enum StorageError {
116    #[error("decode: {0}")]
117    Decode(#[from] DecodeError),
118    #[error("encode: {0}")]
119    Encode(#[from] EncodeError),
120    #[error("io: {0}")]
121    Io(#[from] std::io::Error),
122    #[error("crypt: {0}")]
123    Crypt(#[from] CryptError),
124}
125
126impl From<prost::DecodeError> for StorageError {
127    fn from(from: prost::DecodeError) -> Self {
128        StorageError::Decode(from.into())
129    }
130}
131
132impl From<prost::EncodeError> for StorageError {
133    fn from(from: prost::EncodeError) -> Self {
134        StorageError::Encode(from.into())
135    }
136}
137
138impl From<TryFromSliceError> for StorageError {
139    fn from(slice_error: TryFromSliceError) -> Self {
140        StorageError::Decode(slice_error.into())
141    }
142}
143
144#[derive(Debug, Default)]
145pub enum WireError {
146    Decode(DecodeError),
147    Encode(EncodeError),
148    NotFound,
149    #[default]
150    Unsupported,
151    Verification,
152}
153
154impl Display for WireError {
155    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
156        match self {
157            WireError::Decode(error) => f.write_str(&format!("WireError::Decode({})", error)),
158            WireError::Encode(error) => f.write_str(&format!("WireError::Encode({})", error)),
159            WireError::NotFound => f.write_str("WireError::NotFound"),
160            WireError::Unsupported => f.write_str("WireError::Unsupported"),
161            WireError::Verification => f.write_str("WireError::Verification"),
162        }
163    }
164}
165
166impl Error for WireError {}
167
168impl From<TryFromSliceError> for WireError {
169    fn from(slice_error: TryFromSliceError) -> Self {
170        WireError::Decode(slice_error.into())
171    }
172}
173
174impl From<DecodeError> for WireError {
175    fn from(decode_error: DecodeError) -> Self {
176        WireError::Decode(decode_error)
177    }
178}
179
180impl From<EncodeError> for WireError {
181    fn from(encode_error: EncodeError) -> Self {
182        WireError::Encode(encode_error)
183    }
184}
185
186impl From<prost::UnknownEnumValue> for WireError {
187    fn from(unknown_enum_value: prost::UnknownEnumValue) -> Self {
188        WireError::Decode(DecodeError::from(unknown_enum_value))
189    }
190}
191
192#[cfg(feature = "websocket")]
193#[derive(Debug, thiserror::Error, Copy, Clone, Eq, PartialEq)]
194pub enum GenericWebSocketError {
195    #[error("unsupported")]
196    Unsupported,
197    #[error("websocket")]
198    WebSocket,
199    #[error("decode")]
200    Decode,
201    #[error("internal")]
202    Internal,
203}
204
205#[cfg(feature = "websocket")]
206impl GenericWebSocketError {
207    pub fn into_communication<T: CommunicableType + From<Self>>(self) -> Communication<T> {
208        Communication::new(self.into())
209    }
210}