This commit is contained in:
2023-09-21 23:52:00 -04:00
parent 18383c9e20
commit ac89ef0821
2 changed files with 153 additions and 9 deletions

View File

@@ -1,14 +1,134 @@
pub fn add(left: usize, right: usize) -> usize {
left + right
#![no_std] #![feature(negative_impls, auto_traits)]
extern crate alloc;
use core::panic::Location;
use alloc::boxed::Box;
use alloc::format;
use alloc::string::String;
use core::fmt::{Debug, Display, Formatter};
use core::any::Any;
// ==============================
// Anything
// ==============================
auto trait NotAnything {}
impl !NotAnything for Anything {}
pub struct Anything {
error: Box<dyn DynError>,
#[cfg(debug_assertions)]
origin: &'static Location<'static>,
}
#[cfg(test)]
mod tests {
use super::*;
impl Anything {
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
#[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)
}
}
// ==============================
// Anything
// ==============================
auto trait NotNothing {}
impl !NotNothing for Nothing {}
#[derive(Debug)]
pub struct Nothing;
impl<T: NotNothing> From<T> for Nothing {
fn from(_: T) -> Self { Nothing }
}