1#![cfg_attr(feature = "nightly", feature(likely_unlikely))]
3
4use core::fmt::Debug;
5use core::fmt::Display;
6use hal::mem::PhysAddr;
7
8#[cfg(not(feature = "nightly"))]
10#[allow(unused_imports)]
11pub(crate) use core::convert::{identity as likely, identity as unlikely};
12
13#[cfg(feature = "nightly")]
14pub(crate) use core::hint::{likely, unlikely};
15
16pub type Result<T> = core::result::Result<T, Error>;
17
18#[macro_export]
21macro_rules! bug {
22 () => {
23 panic!("BUG at {}:{}", file!(), line!());
24 };
25 ($fmt:literal $(, $arg:expr)* $(,)?) => {{
26 panic!(concat!("BUG at {}:{}: ", $fmt), file!(), line!() $(, $arg)*);
27 }};
28}
29
30#[macro_export]
31macro_rules! warn {
32 () => {
33 kprintln!("WARN at {}:{}", file!(), line!());
34 };
35 ($fmt:literal $(, $arg:expr)* $(,)?) => {{
36 kprintln!(concat!("WARN at {}:{}: ", $fmt), file!(), line!() $(, $arg)*);
37 }};
38}
39
40macro_rules! bug_on {
43 ($cond:expr) => {{
44 let cond = $cond;
45 #[allow(unused_unsafe)]
46 if unsafe { $crate::error::unlikely(cond) } {
47 panic!("BUG({}) at {}:{}", stringify!($cond), file!(), line!());
48 }
49 }};
50 ($cond:expr, $fmt:literal $(, $arg:expr)* $(,)?) => {{
51 let cond = $cond;
52 #[allow(unused_unsafe)]
53 if unsafe { $crate::error::unlikely(cond) } {
54 panic!(concat!("BUG({}) at {}:{}: ", $fmt), stringify!($cond), file!(), line!() $(, $arg)*);
55 }
56 }};
57}
58
59#[allow(unused_macros)]
60macro_rules! warn_on {
61 ($cond:expr) => {{
62 let cond = $cond;
63 #[allow(unused_unsafe)]
64 if unsafe { $crate::error::unlikely(cond) } {
65 kprintln!("WARN({}) at {}:{}", stringify!($cond), file!(), line!());
66 }
67 }};
68 ($cond:expr, $fmt:literal $(, $arg:expr)* $(,)?) => {{
69 let cond = $cond;
70 #[allow(unused_unsafe)]
71 if unsafe { $crate::error::unlikely(cond) } {
72 kprintln!(concat!("WARN({}) at {}:{}: ", $fmt), stringify!($cond), file!(), line!() $(, $arg)*);
73 }
74 }};
75}
76
77macro_rules! kerr {
78 ($kind:ident) => {
79 $crate::error::Error::new($crate::error::Kind::$kind)
80 };
81 ($kind:expr, $msg:expr) => {
82 use $crate::error::Error;
83 #[cfg(feature = "error-msg")]
84 {
85 Error::new($crate::error::Kind::$kind).with_msg($msg)
86 }
87 #[cfg(not(feature = "error-msg"))]
88 {
89 Error::new($crate::error::Kind::$kind)
90 }
91 };
92}
93
94#[proc_macros::fmt]
95#[allow(dead_code)]
96#[derive(Clone, PartialEq, Eq)]
97pub enum Kind {
98 InvalidAlign,
99 OutOfMemory,
100 InvalidSize,
101 InvalidAddress(PhysAddr),
102 InvalidArgument,
103 NotFound,
104 Hal(hal::Error),
105}
106
107impl Display for Kind {
108 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
109 match self {
110 Kind::InvalidAlign => write!(f, "Invalid alignment"),
111 Kind::OutOfMemory => write!(f, "Out of memory"),
112 Kind::InvalidSize => write!(f, "Invalid size"),
113 Kind::InvalidAddress(addr) => write!(f, "Invalid address: {addr:#x}"),
114 Kind::InvalidArgument => write!(f, "Invalid argument"),
115 Kind::NotFound => write!(f, "Not found"),
116 Kind::Hal(e) => write!(f, "HAL error: {e:?}"),
117 }
118 }
119}
120
121pub struct Error {
122 pub kind: Kind,
123 #[cfg(feature = "error-msg")]
124 msg: Option<&'static str>,
125}
126
127impl Error {
128 pub fn new(kind: Kind) -> Self {
129 #[cfg(feature = "error-msg")]
130 {
131 Self { kind, msg: None }
132 }
133 #[cfg(not(feature = "error-msg"))]
134 {
135 Self { kind }
136 }
137 }
138
139 #[cfg(feature = "error-msg")]
140 pub fn with_msg(mut self, msg: &'static str) -> Self {
141 self.msg = Some(msg);
142 self
143 }
144}
145
146impl Debug for Error {
147 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
148 #[cfg(feature = "error-msg")]
149 {
150 match self.msg {
151 Some(msg) => write!(f, "{}: {}", self.kind, msg),
152 None => write!(f, "{}", self.kind),
153 }
154 }
155 #[cfg(not(feature = "error-msg"))]
156 {
157 write!(f, "{}", self.kind)
158 }
159 }
160}
161
162impl Display for Error {
163 #[cfg(not(feature = "error-msg"))]
164 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
165 write!(f, "{}", self.kind)
166 }
167
168 #[cfg(feature = "error-msg")]
169 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
170 match self.msg {
171 Some(msg) => write!(f, "{}: {}", self.kind, msg),
172 None => write!(f, "{}", self.kind),
173 }
174 }
175}
176
177impl From<hal::Error> for Error {
178 fn from(e: hal::Error) -> Self {
179 Self::new(Kind::Hal(e))
180 }
181}
182
183impl PartialEq for Error {
184 fn eq(&self, other: &Self) -> bool {
185 self.kind == other.kind
186 }
187}