diff options
Diffstat (limited to 'crates/ra_hir/src/debug.rs')
-rw-r--r-- | crates/ra_hir/src/debug.rs | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/crates/ra_hir/src/debug.rs b/crates/ra_hir/src/debug.rs new file mode 100644 index 000000000..5a835741d --- /dev/null +++ b/crates/ra_hir/src/debug.rs | |||
@@ -0,0 +1,64 @@ | |||
1 | use std::{cell::Cell, fmt}; | ||
2 | |||
3 | use ra_db::{CrateId, FileId}; | ||
4 | |||
5 | use crate::{db::HirDatabase, Crate, Module, Name}; | ||
6 | |||
7 | impl Crate { | ||
8 | pub fn debug(self, db: &impl HirDebugDatabase) -> impl fmt::Debug + '_ { | ||
9 | debug_fn(move |fmt| db.debug_crate(self, fmt)) | ||
10 | } | ||
11 | } | ||
12 | |||
13 | impl Module { | ||
14 | pub fn debug(self, db: &impl HirDebugDatabase) -> impl fmt::Debug + '_ { | ||
15 | debug_fn(move |fmt| db.debug_module(self, fmt)) | ||
16 | } | ||
17 | } | ||
18 | |||
19 | pub trait HirDebugHelper: HirDatabase { | ||
20 | fn crate_name(&self, _krate: CrateId) -> Option<String> { | ||
21 | None | ||
22 | } | ||
23 | fn file_path(&self, _file_id: FileId) -> Option<String> { | ||
24 | None | ||
25 | } | ||
26 | } | ||
27 | |||
28 | pub trait HirDebugDatabase { | ||
29 | fn debug_crate(&self, krate: Crate, fmt: &mut fmt::Formatter<'_>) -> fmt::Result; | ||
30 | fn debug_module(&self, module: Module, fmt: &mut fmt::Formatter<'_>) -> fmt::Result; | ||
31 | } | ||
32 | |||
33 | impl<DB: HirDebugHelper> HirDebugDatabase for DB { | ||
34 | fn debug_crate(&self, krate: Crate, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
35 | let mut builder = fmt.debug_tuple("Crate"); | ||
36 | match self.crate_name(krate.crate_id) { | ||
37 | Some(name) => builder.field(&name), | ||
38 | None => builder.field(&krate.crate_id), | ||
39 | } | ||
40 | .finish() | ||
41 | } | ||
42 | |||
43 | fn debug_module(&self, module: Module, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
44 | let file_id = module.definition_source(self).file_id.original_file(self); | ||
45 | let path = self.file_path(file_id); | ||
46 | fmt.debug_struct("Module") | ||
47 | .field("name", &module.name(self).unwrap_or_else(Name::missing)) | ||
48 | .field("path", &path.unwrap_or_else(|| "N/A".to_string())) | ||
49 | .finish() | ||
50 | } | ||
51 | } | ||
52 | |||
53 | fn debug_fn(f: impl FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result) -> impl fmt::Debug { | ||
54 | struct DebugFn<F>(Cell<Option<F>>); | ||
55 | |||
56 | impl<F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result> fmt::Debug for DebugFn<F> { | ||
57 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
58 | let f = self.0.take().unwrap(); | ||
59 | f(fmt) | ||
60 | } | ||
61 | } | ||
62 | |||
63 | DebugFn(Cell::new(Some(f))) | ||
64 | } | ||