1#![warn(missing_docs)]
2#![warn(clippy::std_instead_of_core)]
3#![warn(clippy::std_instead_of_alloc)]
4#![forbid(unsafe_code)]
5#![doc = include_str!("../README.md")]
6
7pub use facet_testhelpers_macros::test;
8
9use log::{Level, LevelFilter, Log, Metadata, Record};
10use owo_colors::{OwoColorize, Style};
11use std::io::Write;
12use std::sync::LazyLock;
13
14struct SimpleLogger;
15
16impl Log for SimpleLogger {
17 fn enabled(&self, _metadata: &Metadata) -> bool {
18 true
19 }
20
21 fn log(&self, record: &Record) {
22 let level_style = match record.level() {
24 Level::Error => Style::new().fg_rgb::<243, 139, 168>(), Level::Warn => Style::new().fg_rgb::<249, 226, 175>(), Level::Info => Style::new().fg_rgb::<166, 227, 161>(), Level::Debug => Style::new().fg_rgb::<137, 180, 250>(), Level::Trace => Style::new().fg_rgb::<148, 226, 213>(), };
30
31 eprintln!(
33 "{} - {}: {}",
34 record.level().style(level_style),
35 record
36 .target()
37 .style(Style::new().fg_rgb::<137, 180, 250>()), record.args()
39 );
40 }
41
42 fn flush(&self) {
43 let _ = std::io::stderr().flush();
44 }
45}
46
47static LOGGER_INIT: LazyLock<()> = LazyLock::new(|| {
52 let logger = Box::new(SimpleLogger);
53 let _ = log::set_boxed_logger(logger);
54 log::set_max_level(LevelFilter::Trace);
55});
56
57pub fn setup() {
75 let is_nextest = std::env::var("NEXTEST").as_deref() == Ok("1");
77 if !is_nextest {
78 static NEXTEST_WARNING: LazyLock<()> = LazyLock::new(|| {
79 eprintln!(
80 "💡 Tip: Consider using `cargo nextest run` for better test output and performance."
81 );
82 eprintln!(" Install with: cargo install cargo-nextest");
83 eprintln!(" More info: https://nexte.st");
84 eprintln!();
85 });
86 *NEXTEST_WARNING;
87 }
88
89 *LOGGER_INIT;
91}
92
93#[derive(Debug)]
96pub struct IPanic;
97
98impl<E> From<E> for IPanic
99where
100 E: core::error::Error + Send + Sync,
101{
102 #[track_caller]
103 fn from(value: E) -> Self {
104 panic!("from: {}: {value}", core::panic::Location::caller())
105 }
106}