mod.rs
1 #![feature(anonymous_lifetime_in_impl_trait, gen_blocks, if_let_guard)] 2 #![allow(unstable_name_collisions)] // Itertools::intersperse 3 4 use std::fmt; 5 6 mod color; 7 pub use color::{ 8 COLORS, 9 STYLE_GUTTER, 10 STYLE_HEADER_POSITION, 11 }; 12 13 pub mod report; 14 pub mod style; 15 16 pub mod terminal; 17 18 pub const INDENT: &str = " "; 19 #[expect(clippy::cast_possible_wrap)] 20 pub const INDENT_WIDTH: isize = INDENT.len() as isize; 21 22 pub trait Debug { 23 fn debug_styled(&self, writer: &mut dyn Write) -> fmt::Result; 24 } 25 26 pub trait Display { 27 fn display_styled(&self, writer: &mut dyn Write) -> fmt::Result; 28 } 29 30 pub fn display(display: &impl fmt::Display) -> impl Display { 31 struct FmtDisplay<'a, D: fmt::Display>(&'a D); 32 33 impl<D: fmt::Display> Display for FmtDisplay<'_, D> { 34 fn display_styled(&self, writer: &mut dyn Write) -> fmt::Result { 35 write!(writer, "{inner}", inner = self.0) 36 } 37 } 38 39 FmtDisplay(display) 40 } 41 42 pub fn with<W: Write + ?Sized, T>( 43 writer: &mut W, 44 style: style::Style, 45 with: impl FnOnce(&mut W) -> T, 46 ) -> T { 47 let style_previous = writer.get_style(); 48 49 writer.set_style(style); 50 let result = with(writer); 51 52 writer.set_style(style_previous); 53 result 54 } 55 56 pub fn write(writer: &mut dyn Write, styled: &impl Display) -> fmt::Result { 57 styled.display_styled(writer) 58 } 59 60 pub trait Write: fmt::Write { 61 fn width(&self) -> usize { 62 0 63 } 64 65 fn width_max(&self) -> usize { 66 usize::MAX 67 } 68 69 fn get_style(&self) -> style::Style; 70 71 fn set_style(&mut self, style: style::Style); 72 73 fn apply_style(&mut self) -> fmt::Result; 74 75 fn write_report( 76 &mut self, 77 report: &report::Report, 78 location: &dyn Display, 79 source: &report::PositionStr<'_>, 80 ) -> fmt::Result; 81 }