//! FIXME: write short doc here use std::fmt; use crate::db::HirDatabase; pub struct HirFormatter<'a, 'b, DB> { pub db: &'a DB, fmt: &'a mut fmt::Formatter<'b>, buf: String, curr_size: usize, truncate_options: Option<&'a TruncateOptions>, } pub trait HirDisplay { fn hir_fmt(&self, f: &mut HirFormatter) -> fmt::Result; fn display<'a, DB>(&'a self, db: &'a DB) -> HirDisplayWrapper<'a, DB, Self> where Self: Sized, { HirDisplayWrapper(db, self, None) } fn display_truncated<'a, DB>( &'a self, db: &'a DB, truncate_options: &'a TruncateOptions, ) -> HirDisplayWrapper<'a, DB, Self> where Self: Sized, { HirDisplayWrapper(db, self, Some(truncate_options)) } } impl<'a, 'b, DB> HirFormatter<'a, 'b, DB> where DB: HirDatabase, { pub fn write_joined( &mut self, iter: impl IntoIterator, sep: &str, ) -> fmt::Result { let mut first = true; for e in iter { if !first { write!(self, "{}", sep)?; } first = false; e.hir_fmt(self)?; } Ok(()) } /// This allows using the `write!` macro directly with a `HirFormatter`. pub fn write_fmt(&mut self, args: fmt::Arguments) -> fmt::Result { // We write to a buffer first to track output size self.buf.clear(); fmt::write(&mut self.buf, args)?; self.curr_size += self.buf.len(); // Then we write to the internal formatter from the buffer self.fmt.write_str(&self.buf) } pub fn should_truncate(&self) -> bool { if let Some(max_size) = self.truncate_options.and_then(|options| options.max_length) { self.curr_size >= max_size } else { false } } pub fn should_display_default_types(&self) -> bool { self.truncate_options.map(|options| options.show_default_types).unwrap_or(true) } } pub struct TruncateOptions { pub max_length: Option, pub show_default_types: bool, } pub struct HirDisplayWrapper<'a, DB, T>(&'a DB, &'a T, Option<&'a TruncateOptions>); impl<'a, DB, T> fmt::Display for HirDisplayWrapper<'a, DB, T> where DB: HirDatabase, T: HirDisplay, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.1.hir_fmt(&mut HirFormatter { db: self.0, fmt: f, buf: String::with_capacity(20), curr_size: 0, truncate_options: self.2, }) } }