1#![cfg_attr(not(test), no_std)]
13#![feature(clamp)]
14#![feature(alloc_error_handler)]
15#![feature(negative_impls)]
16#![cfg_attr(test, feature(proc_macro_hygiene))]
17
18#[cfg(test)]
19#[macro_use]
20extern crate std;
21
22#[cfg(feature = "alloc")]
23#[cfg_attr(feature = "alloc", macro_use)]
24extern crate alloc;
25
26#[macro_use]
27extern crate bitflags;
28
29#[macro_use]
30extern crate cfg_if;
31
32#[cfg(test)]
33extern crate mockall;
34
35#[cfg(all(not(test), feature = "alloc"))]
36pub mod allocator;
37#[cfg(feature = "alloc")]
38pub mod callback;
39pub mod cmd;
40pub mod cstr;
41pub mod device;
42pub mod ffi;
43pub mod fmt;
44pub mod ipc;
45pub mod object;
46pub mod sync;
47pub mod thread;
48pub mod timer;
49
50#[cfg(test)]
51pub(crate) mod mock;
52
53#[cfg(feature = "alloc")]
54pub use alloc::{boxed::Box, rc::Rc, vec::Vec};
55
56#[cfg(feature = "io")]
57pub mod io;
58
59#[cfg(all(not(test), not(feature = "custom-panic")))]
60use core::{fmt::Write, panic::PanicInfo};
61use ffi::rt_err_t;
62
63#[macro_export]
64macro_rules! println {
65 ($fmt:expr) => (print!(concat!($fmt, "\n")));
66 ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
67}
68
69#[macro_export]
70macro_rules! print {
71 ($($arg:tt)*) => ({
72 use core::fmt::Write;
73 let mut writer = $crate::fmt::Console {};
74 writer.write_fmt(format_args!($($arg)*)).unwrap();
75 });
76}
77
78#[cfg(all(not(test), not(feature = "custom-panic")))]
79#[cfg_attr(not(test), panic_handler)]
80fn panic(panic: &PanicInfo<'_>) -> ! {
81 let mut writer = fmt::Console {};
82 writeln!(writer, "{}", panic).ok();
83 loop {}
84}
85
86#[cfg(all(not(test), feature = "alloc"))]
87#[cfg_attr(not(test), alloc_error_handler)]
88fn alloc_error_handler(layout: alloc::alloc::Layout) -> ! {
89 panic!("allocation error: {:?}", layout)
90}
91
92#[derive(Debug)]
94pub enum RtError {
95 Error,
97 TimeOut,
99 Full,
101 Empty,
103 NoMem,
105 NoSys,
107 Busy,
109 IO,
111 Intr,
113 Inval,
115 Unknown,
117}
118
119pub type Result<R> = core::result::Result<R, RtError>;
120
121impl RtError {
122 pub fn from_code(err: rt_err_t) -> Option<Self> {
123 let err = err.abs() as u32;
124 match err {
125 ffi::RT_EOK => None,
126 ffi::RT_ETIMEOUT => Some(RtError::TimeOut),
127 ffi::RT_EFULL => Some(RtError::Full),
128 ffi::RT_EEMPTY => Some(RtError::Empty),
129 ffi::RT_ENOMEM => Some(RtError::NoMem),
130 ffi::RT_ENOSYS => Some(RtError::NoSys),
131 ffi::RT_EBUSY => Some(RtError::Busy),
132 ffi::RT_EIO => Some(RtError::IO),
133 ffi::RT_EINTR => Some(RtError::Intr),
134 ffi::RT_EINVAL => Some(RtError::Inval),
135 _ => Some(RtError::Unknown),
136 }
137 }
138 pub fn from_code_none<R>(err: rt_err_t, ok: R) -> Result<R> {
139 Self::from_code(err).map_or(Ok(ok), |e| Err(e))
140 }
141 pub fn from_code_none_then<F, R>(err: rt_err_t, ok: F) -> Result<R>
142 where
143 F: FnOnce() -> R,
144 {
145 Self::from_code(err).map_or_else(|| Ok(ok()), |e| Err(e))
146 }
147
148 pub fn to_code(&self) -> rt_err_t {
149 let code = match self {
150 RtError::Error => ffi::RT_EOK,
151 RtError::TimeOut => ffi::RT_ETIMEOUT,
152 RtError::Full => ffi::RT_EFULL,
153 RtError::Empty => ffi::RT_EEMPTY,
154 RtError::NoMem => ffi::RT_ENOMEM,
155 RtError::NoSys => ffi::RT_ENOSYS,
156 RtError::Busy => ffi::RT_EBUSY,
157 RtError::IO => ffi::RT_EIO,
158 RtError::Intr => ffi::RT_EINTR,
159 RtError::Inval => ffi::RT_EINVAL,
160 RtError::Unknown => ffi::RT_EINVAL + 1,
161 };
162 -(code as rt_err_t)
163 }
164}