1#[cfg(target_os = "macos")]
5mod sys_err {
6 #[cfg(not(feature = "std"))]
7 mod internal {
8 use core::fmt;
9
10 #[derive(Debug)]
11 pub(crate) struct SysErr;
12
13 impl fmt::Display for SysErr {
14 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15 f.write_str("system error")
16 }
17 }
18
19 impl SysErr {
20 pub fn create() -> Self {
21 Self
22 }
23
24 pub fn create_anyhow() -> anyhow::Error {
25 anyhow::anyhow!(Self::create())
26 }
27 }
28 }
29
30 #[cfg(feature = "std")]
31 mod internal {
32 use core::fmt;
33
34 #[derive(Debug, thiserror::Error)]
35 pub(crate) struct SysErr(std::io::Error);
36
37 impl fmt::Display for SysErr {
38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39 write!(f, "system error: {}", self.0)
40 }
41 }
42
43 impl SysErr {
44 pub fn create() -> Self {
45 Self(std::io::Error::last_os_error())
46 }
47
48 pub fn create_anyhow() -> anyhow::Error {
49 anyhow::anyhow!(Self::create())
50 }
51 }
52 }
53
54 pub(crate) use internal::SysErr;
55}
56
57#[cfg(target_os = "macos")]
58pub(crate) use sys_err::SysErr;
59
60pub(crate) mod private {
62 use core::fmt;
63
64 #[derive(Debug, Clone)]
67 #[cfg_attr(feature = "std", derive(thiserror::Error))]
68 pub(crate) struct AllocError(core::alloc::Layout);
69
70 impl fmt::Display for AllocError {
71 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72 f.write_str("allocation error, possibly OOM")
73 }
74 }
75
76 impl AllocError {
77 #[must_use]
79 pub(crate) fn new(layout: core::alloc::Layout) -> Self {
80 Self(layout)
81 }
82 }
83
84 pub(crate) fn alloc_err_from_size_align(size: usize, align: usize) -> anyhow::Error {
85 let layout = core::alloc::Layout::from_size_align(size, align);
86 match layout {
87 Ok(layout) => anyhow::anyhow!(AllocError::new(layout)),
88 Err(layout_err) => anyhow::anyhow!(layout_err),
89 }
90 }
91
92 pub(crate) trait ResultExt {
93 type T;
94 fn map_anyhow(self) -> anyhow::Result<Self::T>;
95 }
96
97 impl<T, E: Send + Sync + fmt::Debug + fmt::Display + 'static> ResultExt
98 for core::result::Result<T, E>
99 {
100 type T = T;
101
102 fn map_anyhow(self) -> anyhow::Result<Self::T> {
103 self.map_err(|e| anyhow::anyhow!(e))
104 }
105 }
106}
107
108pub type Result = core::result::Result<(), Error>;
112
113#[must_use]
121#[cfg_attr(feature = "std", derive(thiserror::Error))]
122#[derive(Debug)]
123pub enum Error {
124 BeingTraced(Traced),
127 Err(anyhow::Error),
130}
131
132#[derive(Debug, Clone)]
135pub struct Traced {
136 #[cfg(unix)]
137 pid: Option<rustix::process::Pid>,
138}
139
140#[cfg(unix)]
141impl Traced {
142 pub(crate) fn from_pid(pid: rustix::process::Pid) -> Self {
143 Self { pid: Some(pid) }
144 }
145}
146
147#[cfg(not(unix))]
148impl Traced {
149 pub(crate) const DEFAULT: Self = Self {};
150}
151
152impl core::fmt::Display for Traced {
153 #[cfg(unix)]
154 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
155 match self.pid {
156 Some(pid) => write!(
157 formatter,
158 "program is being traced by the process with pid {}",
159 pid.as_raw_nonzero()
160 ),
161 None => formatter.write_str("program is being traced"),
162 }
163 }
164
165 #[cfg(not(unix))]
166 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
167 formatter.write_str("program is being traced")
168 }
169}
170
171impl core::fmt::Display for Error {
172 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
173 match self {
174 Self::BeingTraced(tr) => tr.fmt(formatter),
175 Self::Err(e) => e.fmt(formatter),
176 }
177 }
178}
179
180impl From<anyhow::Error> for Error {
181 fn from(err: anyhow::Error) -> Self {
182 Error::Err(err)
183 }
184}
185
186pub(crate) trait ResultExt {
187 fn create_ok() -> Self;
188 fn create_being_traced(traced: Traced) -> Self;
189 fn create_err(e: anyhow::Error) -> Self;
190}
191
192impl ResultExt for Result {
193 fn create_ok() -> Self {
194 Ok(())
195 }
196
197 fn create_being_traced(traced: Traced) -> Self {
198 Err(Error::BeingTraced(traced))
199 }
200
201 fn create_err(e: anyhow::Error) -> Self {
202 Err(Error::Err(e))
203 }
204}