]> git.lizzy.rs Git - rust.git/blob - crates/ra_hir/src/ty/display.rs
Move type inlay hint truncation to language server
[rust.git] / crates / ra_hir / src / ty / display.rs
1 //! FIXME: write short doc here
2
3 use std::fmt;
4
5 use crate::db::HirDatabase;
6
7 pub struct HirFormatter<'a, 'b, DB> {
8     pub db: &'a DB,
9     fmt: &'a mut fmt::Formatter<'b>,
10     buf: String,
11     curr_size: usize,
12     max_size: Option<usize>,
13 }
14
15 pub trait HirDisplay {
16     fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result;
17
18     fn display<'a, DB>(&'a self, db: &'a DB) -> HirDisplayWrapper<'a, DB, Self>
19     where
20         Self: Sized,
21     {
22         HirDisplayWrapper(db, self, None)
23     }
24
25     fn display_truncated<'a, DB>(
26         &'a self,
27         db: &'a DB,
28         max_size: Option<usize>,
29     ) -> HirDisplayWrapper<'a, DB, Self>
30     where
31         Self: Sized,
32     {
33         HirDisplayWrapper(db, self, max_size)
34     }
35 }
36
37 impl<'a, 'b, DB> HirFormatter<'a, 'b, DB>
38 where
39     DB: HirDatabase,
40 {
41     pub fn write_joined<T: HirDisplay>(
42         &mut self,
43         iter: impl IntoIterator<Item = T>,
44         sep: &str,
45     ) -> fmt::Result {
46         let mut first = true;
47         for e in iter {
48             if !first {
49                 write!(self, "{}", sep)?;
50             }
51             first = false;
52             e.hir_fmt(self)?;
53         }
54         Ok(())
55     }
56
57     /// This allows using the `write!` macro directly with a `HirFormatter`.
58     pub fn write_fmt(&mut self, args: fmt::Arguments) -> fmt::Result {
59         // We write to a buffer first to track output size
60         self.buf.clear();
61         fmt::write(&mut self.buf, args)?;
62         self.curr_size += self.buf.len();
63
64         // Then we write to the internal formatter from the buffer
65         self.fmt.write_str(&self.buf)
66     }
67
68     pub fn should_truncate(&self) -> bool {
69         if let Some(max_size) = self.max_size {
70             self.curr_size >= max_size
71         } else {
72             false
73         }
74     }
75 }
76
77 pub struct HirDisplayWrapper<'a, DB, T>(&'a DB, &'a T, Option<usize>);
78
79 impl<'a, DB, T> fmt::Display for HirDisplayWrapper<'a, DB, T>
80 where
81     DB: HirDatabase,
82     T: HirDisplay,
83 {
84     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
85         self.1.hir_fmt(&mut HirFormatter {
86             db: self.0,
87             fmt: f,
88             buf: String::with_capacity(20),
89             curr_size: 0,
90             max_size: self.2,
91         })
92     }
93 }