anyways/
lib.rs

1#![feature(trait_alias)]
2//! # Anyways
3//! Anyways is a dynamic error reporting library.
4//! Which allows you to not worry about creating error types and instead handling errors.
5//!
6//! This library is not recommended for other libraries to use and instead it is
7//! advised to use something like `thiserror` to easily generate concrete types to make it easier for other people to use the library.
8//! Instead this is intended for applications where a ton of libraries are used to create a product and where making a concrete error type is not feasible.
9//!
10//! ## Panic Processes
11//! 1. Audit gets made
12//! 2. The AuditProcessor removes useless information and makes the information more digestible
13//! 3. The AuditFormatter formats the audit sections to the output.
14use owo_colors::{Style};
15use crate::audit::Audit;
16use crate::formatter::{AnywaysAuditFormatter, AuditFormatter};
17use crate::processor::{AnywaysAuditProcessorBuilder, AuditProcessor};
18
19pub mod audit;
20pub mod ext;
21pub mod formatter;
22pub mod processor;
23mod align;
24
25pub type Result<T, E = Audit> = std::result::Result<T, E>;
26
27static mut AUDIT_FORMATTER: Option<Box<dyn AuditFormatter>> = None;
28static mut AUDIT_PROCESSOR: Option<Box<dyn AuditProcessor>> = None;
29
30pub fn set_audit_formatter(formatter: impl AuditFormatter + 'static) {
31    unsafe {
32        AUDIT_FORMATTER = Some(Box::new(formatter));
33    }
34}
35
36pub fn set_audit_processor(processor: impl AuditProcessor + 'static) {
37    unsafe {
38        AUDIT_PROCESSOR = Some(Box::new(processor));
39    }
40}
41
42pub fn get_audit_formatter() -> &'static dyn AuditFormatter {
43    unsafe {
44        if AUDIT_FORMATTER.is_none() {
45            set_audit_formatter(AnywaysAuditFormatter::default());
46        }
47        AUDIT_FORMATTER.as_deref().unwrap()
48    }
49}
50
51pub fn get_audit_processor() -> &'static dyn AuditProcessor {
52    unsafe {
53        if AUDIT_PROCESSOR.is_none() {
54            set_audit_processor(AnywaysAuditProcessorBuilder::default().build());
55        }
56        AUDIT_PROCESSOR.as_deref().unwrap()
57    }
58}
59
60#[cfg(test)]
61mod tests {
62    use std::fs::File;
63    use owo_colors::{AnsiColors, DynColors};
64    use crate::audit::{AuditSection, AuditSectionEntry};
65
66    use crate::ext::AuditExt;
67    use crate::Result;
68
69    #[test]
70    fn thigns() -> Result<()> {
71        read_plugin_before().wrap_err("Failed to read plugin").wrap(|audit| {
72            audit.custom_sections.push(AuditSection {
73                name: "Dogs".to_string(),
74                color: DynColors::Ansi(AnsiColors::BrightBlue),
75                entries: vec![
76                    AuditSectionEntry::text("Sheril".to_string())
77                ]
78            })
79        })
80    }
81
82    fn read_plugin_before() -> Result<()> {
83        match very_long_module_also_because_i_can_btw_i_need_this_to_see_if_wrapping_works_correctly::read_plugin_very_long_name_because_i_can_hello_there() {
84            Ok(_) => {}
85            Err(err) => {
86                return Err(err);
87            }
88        };
89        Ok(())
90    }
91
92    mod very_long_module_also_because_i_can_btw_i_need_this_to_see_if_wrapping_works_correctly {
93        use std::fs::File;
94        use crate::ext::AuditExt;
95
96        pub(crate) fn read_plugin_very_long_name_because_i_can_hello_there() -> crate::Result<()> {
97            File::open("./your mom is very gay").wrap_err("Failed to find your mom being gay")?;
98
99            Ok(())
100        }
101    }
102}