This commit is contained in:
Jessie
2023-09-22 03:45:53 -04:00
parent c06670e72b
commit ad362d90d5
4 changed files with 124 additions and 138 deletions

107
src/anything.rs Normal file
View File

@@ -0,0 +1,107 @@
use alloc::boxed::Box;
use alloc::format;
use alloc::string::String;
use core::any::Any;
use core::fmt::{Debug, Display, Formatter};
use core::panic::Location;
pub auto trait NotAnything {}
impl !NotAnything for Anything {}
impl <T> NotAnything for Box<T> {}
pub struct Anything {
error: Box<dyn DynError>,
#[cfg(debug_assertions)]
origin: &'static Location<'static>,
}
impl Anything {
#[track_caller]
pub fn new<T: DynError + 'static>(error: T) -> Anything {
Anything {
error: Box::new(error),
origin: Location::caller(),
}
}
#[track_caller]
pub fn new_error<T: DynError + 'static>(error: T) -> Result<(), Anything> {
Err(Anything {
error: Box::new(error),
origin: Location::caller(),
})
}
#[track_caller]
pub fn assert<T: DynError + 'static>(error_if_false: bool, error: T) -> Result<(), Anything> {
if error_if_false { return Ok(()) }
Err(Anything {
error: Box::new(error),
origin: Location::caller(),
})
}
pub fn get_error(&self) -> &dyn Any {
self.error.as_any()
}
pub fn get_origin(&self) -> Option<Location<'static>> {
#[cfg(debug_assertions)]
return Some(self.origin.clone());
#[cfg(not(debug_assertions))]
return None;
}
}
impl Display for Anything {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
write!(f,
"[{}:{}:{}] {:?}",
self.origin.file(),
self.origin.line(),
self.origin.column(),
self.error.format()
)
}
}
impl Debug for Anything {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
write!(f,
"'{:?}'\n at {}:{}:{}",
self.error.format(),
self.origin.file(),
self.origin.line(),
self.origin.column()
)
}
}
impl<T: DynError + 'static> From<T> for Anything {
#[track_caller]
fn from(value: T) -> Self {
Anything {
error: Box::new(value),
origin: Location::caller(),
}
}
}
pub trait DynError {
fn as_any(&self) -> &dyn Any;
fn format(&self) -> String;
}
impl<T: Any + NotAnything + Debug > DynError for T {
fn as_any(&self) -> &dyn Any {
self as &dyn Any
}
fn format(&self) -> String {
format!("{:?}", self)
}
}

View File

@@ -1,11 +0,0 @@
#![allow(suspicious_auto_trait_impls)]
pub auto trait NotNothing {}
impl !NotNothing for super::Nothing {}
pub auto trait NotAnything {}
impl !NotAnything for super::Anything {}
impl <T> NotNothing for alloc::boxed::Box<T> {}
impl <T> NotAnything for alloc::boxed::Box<T> {}

View File

@@ -1,131 +1,10 @@
#![no_std] #![feature(negative_impls, auto_traits)] #![no_std] #![feature(negative_impls, auto_traits, const_type_id)]
#![allow(suspicious_auto_trait_impls)]
extern crate alloc; extern crate alloc;
use core::panic::Location; pub(crate) mod anything;
use alloc::boxed::Box; pub(crate) mod nothing;
use alloc::format;
use alloc::string::String;
use core::fmt::{Debug, Display, Formatter};
use core::any::Any;
use crate::autotraits::{NotAnything, NotNothing};
mod autotraits; pub use anything::*;
pub use nothing::*;
// ==============================
// Anything
// ==============================
pub struct Anything {
error: Box<dyn DynError>,
#[cfg(debug_assertions)]
origin: &'static Location<'static>,
}
impl Anything {
#[track_caller]
pub fn new<T: DynError + 'static>(error: T) -> Anything {
Anything {
error: Box::new(error),
origin: Location::caller(),
}
}
#[track_caller]
pub fn new_error<T: DynError + 'static>(error: T) -> Result<(), Anything> {
Err(Anything {
error: Box::new(error),
origin: Location::caller(),
})
}
#[track_caller]
pub fn assert<T: DynError + 'static>(error_if_false: bool, error: T) -> Result<(), Anything> {
if error_if_false { return Ok(()) }
Err(Anything {
error: Box::new(error),
origin: Location::caller(),
})
}
pub fn get_error(&self) -> &dyn Any {
self.error.as_any()
}
pub fn get_origin(&self) -> Option<Location<'static>> {
#[cfg(debug_assertions)]
return Some(self.origin.clone());
#[cfg(not(debug_assertions))]
return None;
}
}
impl Display for Anything {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
write!(f,
"[{}:{}:{}] {:?}",
self.origin.file(),
self.origin.line(),
self.origin.column(),
self.error.format()
)
}
}
impl Debug for Anything {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
write!(f,
"'{:?}'\n at {}:{}:{}",
self.error.format(),
self.origin.file(),
self.origin.line(),
self.origin.column()
)
}
}
impl<T: DynError + 'static> From<T> for Anything {
#[track_caller]
fn from(value: T) -> Self {
Anything {
error: Box::new(value),
origin: Location::caller(),
}
}
}
// ==============================
// Error Type
// ==============================
pub trait DynError {
fn as_any(&self) -> &dyn Any;
fn format(&self) -> String;
}
impl<T: Any + NotAnything + Debug > DynError for T {
fn as_any(&self) -> &dyn Any {
self as &dyn Any
}
fn format(&self) -> String {
format!("{:?}", self)
}
}
// ==============================
// Nothing
// ==============================
#[derive(Debug)]
pub struct Nothing;
impl<T: NotNothing> From<T> for Nothing {
fn from(_: T) -> Self { Nothing }
}

11
src/nothing.rs Normal file
View File

@@ -0,0 +1,11 @@
pub auto trait NotNothing {}
impl !NotNothing for Nothing {}
impl <T> NotNothing for alloc::boxed::Box<T> {}
#[derive(Debug)]
pub struct Nothing;
impl<T: NotNothing> From<T> for Nothing {
fn from(_: T) -> Self { Nothing }
}