1use std::{
2 cell::{BorrowError, BorrowMutError},
3 fmt::Display,
4 panic::Location,
5};
6
7#[derive(Debug, Clone)]
9pub struct Error {
10 kind: ErrorKind,
11 message: String,
12 location: &'static Location<'static>,
13}
14
15impl Error {
16 #[track_caller]
17 #[allow(unused)]
18 pub(crate) fn new<S: ToString>(kind: ErrorKind, message: S) -> Self {
19 Error {
20 kind,
21 message: message.to_string(),
22 location: Location::caller(),
23 }
24 }
25
26 #[track_caller]
27 pub(crate) fn result<T, S: ToString>(kind: ErrorKind, message: S) -> Result<T, Self> {
28 Err(Error {
29 kind,
30 message: message.to_string(),
31 location: Location::caller(),
32 })
33 }
34
35 pub fn kind(&self) -> ErrorKind {
37 self.kind
38 }
39
40 pub fn message(&self) -> &str {
42 &self.message
43 }
44
45 pub fn location(&self) -> &'static Location<'static> {
47 self.location
48 }
49}
50
51impl Display for Error {
52 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53 write!(f, "{}", self.message)
54 }
55}
56
57impl std::error::Error for Error {}
58
59#[derive(Debug, Clone, Copy)]
61#[non_exhaustive]
62pub enum ErrorKind {
63 BrokenChain,
64 UsageConflict,
65 WrongPinType,
66 PinGroupLimit,
67 Other,
68}
69
70impl From<&str> for Error {
71 #[track_caller]
72 fn from(value: &str) -> Self {
73 Error {
74 kind: ErrorKind::Other,
75 message: value.to_string(),
76 location: Location::caller(),
77 }
78 }
79}
80
81impl From<String> for Error {
82 #[track_caller]
83 fn from(value: String) -> Self {
84 Error {
85 kind: ErrorKind::Other,
86 message: value,
87 location: Location::caller(),
88 }
89 }
90}
91
92impl From<BorrowError> for Error {
93 #[track_caller]
94 fn from(_: BorrowError) -> Self {
95 Error {
96 kind: ErrorKind::UsageConflict,
97 message: "scanner is being used by another pin or pin group".into(),
98 location: Location::caller(),
99 }
100 }
101}
102
103impl From<BorrowMutError> for Error {
104 #[track_caller]
105 fn from(_: BorrowMutError) -> Self {
106 Error {
107 kind: ErrorKind::UsageConflict,
108 message: "scanner is being used by another pin or pin group".into(),
109 location: Location::caller(),
110 }
111 }
112}