escvpnet/
error.rs

1use std::{num::TryFromIntError, string::FromUtf8Error};
2
3use crate::packet::Status;
4
5#[derive(Debug)]
6
7pub struct Error {
8    kind: ErrorKind,
9    message: String,
10}
11impl Error {
12    pub fn new(kind: ErrorKind, message: String) -> Self {
13        Self { kind, message }
14    }
15
16    pub fn kind(&self) -> ErrorKind {
17        self.kind.clone()
18    }
19
20    pub fn message(&self) -> String {
21        self.message.clone()
22    }
23}
24#[non_exhaustive]
25#[derive(Debug, Clone)]
26pub enum ErrorKind {
27    Decoding,
28    Encoding,
29    IO(std::io::ErrorKind),
30    Protocol(Status),
31}
32
33impl ToString for ErrorKind {
34    fn to_string(&self) -> String {
35        use ErrorKind::*;
36        match self {
37            Decoding => "Decoding Error".to_string(),
38            Encoding => "Encoding Error".to_string(),
39            IO(kind) => format!("I/O Error ({})", kind.to_string()),
40            Protocol(status) => format!("Protocol Error (status:{status:?})"),
41        }
42    }
43}
44
45impl std::fmt::Display for Error {
46    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47        write!(
48            f,
49            "ESC/VP.net Error: {}, {}",
50            self.kind().to_string(),
51            self.message()
52        )
53    }
54}
55impl std::error::Error for Error {}
56
57impl From<std::io::Error> for Error {
58    fn from(value: std::io::Error) -> Self {
59        Self {
60            kind: ErrorKind::IO(value.kind()),
61            message: value.to_string(),
62        }
63    }
64}
65
66impl From<FromUtf8Error> for Error {
67    fn from(_: FromUtf8Error) -> Self {
68        Self {
69            kind: ErrorKind::Decoding,
70            message: "Error while decoding string".to_string(),
71        }
72    }
73}
74
75impl From<TryFromIntError> for Error {
76    fn from(_: TryFromIntError) -> Self {
77        Self {
78            kind: ErrorKind::Decoding,
79            message: "Collection length too big to be encoded".to_string(),
80        }
81    }
82}
83
84impl From<Status> for Error {
85    fn from(value: Status) -> Self {
86        use Status::*;
87        Self {
88            kind: ErrorKind::Protocol(value.clone()),
89            message: match value {
90                BadRequest => "Bad Request",
91                Unauthorized => "Unauthorized, a password header was expected",
92                Forbidden => "Forbidden, bad password",
93                RequestNotAllowed => "Request not allowed",
94                ServiceUnavailable => "Service Unavalaible",
95                VersionNotSupported => "Version not supported",
96                _ => "This is not supposed to happen",
97            }
98            .to_string(),
99        }
100    }
101}