#[cfg(target_os = "macos")]
mod sys_err {
#[cfg(not(feature = "std"))]
mod internal {
use core::fmt;
#[derive(Debug)]
pub(crate) struct SysErr;
impl fmt::Display for SysErr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("system error")
}
}
impl SysErr {
pub fn create() -> Self {
Self
}
pub fn create_anyhow() -> anyhow::Error {
anyhow::anyhow!(Self::create())
}
}
}
#[cfg(feature = "std")]
mod internal {
use core::fmt;
#[derive(Debug, thiserror::Error)]
pub(crate) struct SysErr(std::io::Error);
impl fmt::Display for SysErr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "system error: {}", self.0)
}
}
impl SysErr {
pub fn create() -> Self {
Self(std::io::Error::last_os_error())
}
pub fn create_anyhow() -> anyhow::Error {
anyhow::anyhow!(Self::create())
}
}
}
pub(crate) use internal::SysErr;
}
#[cfg(target_os = "macos")]
pub(crate) use sys_err::SysErr;
pub(crate) mod private {
use core::fmt;
#[derive(Debug, Clone)]
#[cfg_attr(feature = "std", derive(thiserror::Error))]
pub(crate) struct AllocError(core::alloc::Layout);
impl fmt::Display for AllocError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("allocation error, possibly OOM")
}
}
impl AllocError {
#[must_use]
pub(crate) fn new(layout: core::alloc::Layout) -> Self {
Self(layout)
}
}
pub(crate) fn alloc_err_from_size_align(size: usize, align: usize) -> anyhow::Error {
let layout = core::alloc::Layout::from_size_align(size, align);
match layout {
Ok(layout) => anyhow::anyhow!(AllocError::new(layout)),
Err(layout_err) => anyhow::anyhow!(layout_err),
}
}
pub(crate) trait ResultExt {
type T;
fn map_anyhow(self) -> anyhow::Result<Self::T>;
}
impl<T, E: Send + Sync + fmt::Debug + fmt::Display + 'static> ResultExt
for core::result::Result<T, E>
{
type T = T;
fn map_anyhow(self) -> anyhow::Result<Self::T> {
self.map_err(|e| anyhow::anyhow!(e))
}
}
}
pub type Result = core::result::Result<(), Error>;
#[must_use]
#[cfg_attr(feature = "std", derive(thiserror::Error))]
#[derive(Debug)]
pub enum Error {
BeingTraced(Traced),
Err(anyhow::Error),
}
#[derive(Debug, Clone)]
pub struct Traced {
#[cfg(unix)]
pid: Option<rustix::process::Pid>,
}
#[cfg(unix)]
impl Traced {
pub(crate) fn from_pid(pid: rustix::process::Pid) -> Self {
Self { pid: Some(pid) }
}
}
#[cfg(not(unix))]
impl Traced {
pub(crate) const DEFAULT: Self = Self {};
}
impl core::fmt::Display for Traced {
#[cfg(unix)]
fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self.pid {
Some(pid) => write!(
formatter,
"program is being traced by the process with pid {}",
pid.as_raw_nonzero()
),
None => formatter.write_str("program is being traced"),
}
}
#[cfg(not(unix))]
fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
formatter.write_str("program is being traced")
}
}
impl core::fmt::Display for Error {
fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::BeingTraced(tr) => tr.fmt(formatter),
Self::Err(e) => e.fmt(formatter),
}
}
}
impl From<anyhow::Error> for Error {
fn from(err: anyhow::Error) -> Self {
Error::Err(err)
}
}
pub(crate) trait ResultExt {
fn create_ok() -> Self;
fn create_being_traced(traced: Traced) -> Self;
fn create_err(e: anyhow::Error) -> Self;
}
impl ResultExt for Result {
fn create_ok() -> Self {
Ok(())
}
fn create_being_traced(traced: Traced) -> Self {
Err(Error::BeingTraced(traced))
}
fn create_err(e: anyhow::Error) -> Self {
Err(Error::Err(e))
}
}