2019-09-30 03:58:53 -05:00
|
|
|
//! FIXME: write short doc here
|
|
|
|
|
2019-03-14 16:03:39 -05:00
|
|
|
use std::fmt;
|
|
|
|
|
|
|
|
use crate::db::HirDatabase;
|
|
|
|
|
|
|
|
pub struct HirFormatter<'a, 'b, DB> {
|
|
|
|
pub db: &'a DB,
|
|
|
|
fmt: &'a mut fmt::Formatter<'b>,
|
2019-11-18 11:02:28 -06:00
|
|
|
buf: String,
|
|
|
|
curr_size: usize,
|
2019-12-07 16:54:18 -06:00
|
|
|
truncate_options: Option<&'a TruncateOptions>,
|
2019-03-14 16:03:39 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub trait HirDisplay {
|
|
|
|
fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result;
|
2019-11-18 11:02:28 -06:00
|
|
|
|
2019-03-14 16:03:39 -05:00
|
|
|
fn display<'a, DB>(&'a self, db: &'a DB) -> HirDisplayWrapper<'a, DB, Self>
|
|
|
|
where
|
|
|
|
Self: Sized,
|
|
|
|
{
|
2019-11-18 11:02:28 -06:00
|
|
|
HirDisplayWrapper(db, self, None)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn display_truncated<'a, DB>(
|
|
|
|
&'a self,
|
|
|
|
db: &'a DB,
|
2019-12-07 16:54:18 -06:00
|
|
|
truncate_options: &'a TruncateOptions,
|
2019-11-18 11:02:28 -06:00
|
|
|
) -> HirDisplayWrapper<'a, DB, Self>
|
|
|
|
where
|
|
|
|
Self: Sized,
|
|
|
|
{
|
2019-12-07 16:54:18 -06:00
|
|
|
HirDisplayWrapper(db, self, Some(truncate_options))
|
2019-03-14 16:03:39 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, 'b, DB> HirFormatter<'a, 'b, DB>
|
|
|
|
where
|
|
|
|
DB: HirDatabase,
|
|
|
|
{
|
|
|
|
pub fn write_joined<T: HirDisplay>(
|
|
|
|
&mut self,
|
|
|
|
iter: impl IntoIterator<Item = T>,
|
|
|
|
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 {
|
2019-11-18 11:02:28 -06:00
|
|
|
// 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 {
|
2019-12-07 16:54:18 -06:00
|
|
|
if let Some(max_size) = self.truncate_options.and_then(|options| options.max_length) {
|
2019-11-18 11:02:28 -06:00
|
|
|
self.curr_size >= max_size
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
2019-03-14 16:03:39 -05:00
|
|
|
}
|
2019-12-07 16:54:18 -06:00
|
|
|
|
|
|
|
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<usize>,
|
|
|
|
pub show_default_types: bool,
|
2019-03-14 16:03:39 -05:00
|
|
|
}
|
|
|
|
|
2019-12-07 16:54:18 -06:00
|
|
|
pub struct HirDisplayWrapper<'a, DB, T>(&'a DB, &'a T, Option<&'a TruncateOptions>);
|
2019-03-14 16:03:39 -05:00
|
|
|
|
|
|
|
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 {
|
2019-11-18 11:02:28 -06:00
|
|
|
self.1.hir_fmt(&mut HirFormatter {
|
|
|
|
db: self.0,
|
|
|
|
fmt: f,
|
|
|
|
buf: String::with_capacity(20),
|
|
|
|
curr_size: 0,
|
2019-12-07 16:54:18 -06:00
|
|
|
truncate_options: self.2,
|
2019-11-18 11:02:28 -06:00
|
|
|
})
|
2019-03-14 16:03:39 -05:00
|
|
|
}
|
|
|
|
}
|