diff --git a/src/lib.rs b/src/lib.rs index 7d12d9a..d158245 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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, + + #[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(error: T) -> Anything { + Anything { + error: Box::new(error), + origin: Location::caller(), + } + } + + #[track_caller] + pub fn new_error(error: T) -> Result<(), Anything> { + Err(Anything { + error: Box::new(error), + origin: Location::caller(), + }) + } + + #[track_caller] + pub fn assert(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> { + #[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 From 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 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 From for Nothing { + fn from(_: T) -> Self { Nothing } +} + diff --git a/tests/test.rs b/tests/test.rs index e69de29..6d72f5c 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -0,0 +1,24 @@ +use anything::{Anything, Nothing}; + +pub fn func_1() -> Result<(),Anything> { + Err(())?; + Ok(()) +} + +pub fn func_2() -> Result<(),Anything> { + Err("Hello World")?; + Ok(()) +} + +pub fn func_3() -> Result<(),Nothing> { + Err("Hello World")?; + Ok(()) +} + + +#[test] +pub fn test() { + println!("{:?}", func_1().unwrap_err()); + println!("{:?}", func_2().unwrap_err()); + println!("{:?}", func_3().unwrap_err()); +} \ No newline at end of file