rosu_mem/
error.rs

1use std::{
2    error::Error, fmt::Display, num::ParseIntError, str::Utf8Error,
3    string::FromUtf8Error,
4};
5
6#[derive(Debug)]
7pub enum ProcessError {
8    ProcessNotFound,
9    ExecutablePathNotFound,
10    NotEnoughPermissions,
11    IoError {
12        inner: std::io::Error,
13    },
14    FromUtf8Error,
15    ConvertionError,
16    BadAddress(usize, usize),
17    SignatureNotFound(String),
18    OsError {
19        #[cfg(target_os = "linux")]
20        inner: nix::errno::Errno,
21        #[cfg(target_os = "windows")]
22        inner: windows::core::Error,
23    },
24}
25
26impl From<std::io::Error> for ProcessError {
27    fn from(value: std::io::Error) -> Self {
28        Self::IoError { inner: value }
29    }
30}
31
32impl From<std::num::ParseIntError> for ProcessError {
33    fn from(_: std::num::ParseIntError) -> Self {
34        Self::ConvertionError
35    }
36}
37
38impl From<std::num::TryFromIntError> for ProcessError {
39    fn from(_: std::num::TryFromIntError) -> Self {
40        Self::ConvertionError
41    }
42}
43
44impl From<FromUtf8Error> for ProcessError {
45    fn from(_: FromUtf8Error) -> Self {
46        Self::FromUtf8Error
47    }
48}
49
50impl From<Utf8Error> for ProcessError {
51    fn from(_: Utf8Error) -> Self {
52        Self::FromUtf8Error
53    }
54}
55
56// Linux only
57#[cfg(target_os = "linux")]
58impl From<nix::errno::Errno> for ProcessError {
59    fn from(inner: nix::errno::Errno) -> Self {
60        match inner {
61            nix::errno::Errno::EPERM => Self::NotEnoughPermissions,
62            nix::errno::Errno::ESRCH => Self::ProcessNotFound,
63            _ => Self::OsError { inner },
64        }
65    }
66}
67
68// Windows only
69#[cfg(target_os = "windows")]
70impl From<windows::core::Error> for ProcessError {
71    fn from(inner: windows::core::Error) -> Self {
72        Self::OsError { inner } // TODO add code value
73    }
74}
75
76impl Display for ProcessError {
77    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
78        match self {
79            ProcessError::ProcessNotFound => write!(f, "Process not found!"),
80            ProcessError::IoError { .. } => write!(f, "Got I/O error!"),
81            ProcessError::FromUtf8Error => {
82                write!(f, "Got Error when converting bytes to string!")
83            }
84            ProcessError::ConvertionError => {
85                write!(f, "Got error during type convertion")
86            }
87            ProcessError::SignatureNotFound(v) => {
88                write!(f, "Cannot find signature {}", v)
89            }
90            ProcessError::OsError { .. } => write!(f, "Got OS error"),
91            ProcessError::NotEnoughPermissions => {
92                write!(f, "Not enough permissions to run, please run as sudo")
93            }
94            ProcessError::BadAddress(addr, len) => {
95                let _ = writeln!(f, "Trying to read bad address");
96                writeln!(f, "Address: {:X}, Length: {:X}", addr, len)
97            }
98            ProcessError::ExecutablePathNotFound => {
99                write!(f, "Executable path not found!")
100            }
101        }
102    }
103}
104
105impl std::error::Error for ProcessError {
106    fn source(&self) -> Option<&(dyn Error + 'static)> {
107        match self {
108            ProcessError::ProcessNotFound => None,
109            ProcessError::ExecutablePathNotFound => None,
110            ProcessError::NotEnoughPermissions => None,
111            ProcessError::IoError { inner } => Some(inner),
112            ProcessError::FromUtf8Error => None,
113            ProcessError::ConvertionError => None,
114            ProcessError::SignatureNotFound(_) => None,
115            ProcessError::OsError { inner } => Some(inner),
116            ProcessError::BadAddress(..) => None,
117        }
118    }
119}
120
121#[derive(Debug)]
122pub enum ParseSignatureError {
123    InvalidLength(usize),
124    InvalidInt { inner: ParseIntError },
125}
126
127impl From<ParseIntError> for ParseSignatureError {
128    fn from(inner: ParseIntError) -> Self {
129        Self::InvalidInt { inner }
130    }
131}
132
133impl Error for ParseSignatureError {
134    fn source(&self) -> Option<&(dyn Error + 'static)> {
135        match self {
136            ParseSignatureError::InvalidLength(_) => None,
137            ParseSignatureError::InvalidInt { inner } => Some(inner),
138        }
139    }
140}
141
142impl Display for ParseSignatureError {
143    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
144        match self {
145            ParseSignatureError::InvalidLength(len) => {
146                write!(f, "Invalid string length {len}")
147            }
148            ParseSignatureError::InvalidInt { .. } => {
149                f.write_str("Failed to parse integer")
150            }
151        }
152    }
153}