1use std::fmt;
2
3use itertools::Itertools;
4
5use crate::decl::{
6 legacy::{ExtensionDecl, ModuleDecl},
7 Decl, FieldDecl, FunctionDecl, ImportPathDecl, ParamDecl, StructBody, StructDecl,
8 TypeAliasDecl, VarDecl,
9};
10
11pub trait Tooltip {
12 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result;
13}
14
15impl Tooltip for Decl {
16 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
17 use Decl::*;
18
19 match self {
20 Var(inner) | Const(inner) => Tooltip::fmt(inner, f),
21 TypeAlias(inner) => Tooltip::fmt(inner, f),
22 Struct(inner) => Tooltip::fmt(inner, f),
23 Field(inner) => Tooltip::fmt(inner, f),
24 Function(inner) => Tooltip::fmt(inner, f),
25 Param(inner) => Tooltip::fmt(inner, f),
26 Extension(inner) => Tooltip::fmt(inner, f),
27 ImportPath(inner) => Tooltip::fmt(inner, f),
28 Import(_) => {
29 eprintln!(
30 "WARNING: Tooltip-formatting `#import` declarations is not currently supported"
31 );
32 Ok(())
33 }
34 Module(inner) => Tooltip::fmt(inner, f),
35 }
36 }
37}
38
39impl Tooltip for VarDecl {
40 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
41 if let Some(ref attributes) = self.attributes {
42 writeln!(f, "{}", attributes)?;
43 }
44
45 write!(f, "{}", self.storage)?;
46 if let Some(ref qual) = self.storage_qualifiers {
47 write!(f, "<{}>", qual.iter().join(", "))?;
48 }
49
50 write!(f, " {}", self.name)?;
51 if let Some(ref ty) = self.ty {
52 write!(f, ": {}", ty)?;
53 }
54
55 Ok(())
56 }
57}
58
59impl Tooltip for TypeAliasDecl {
60 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
61 write!(f, "TODO")
62 }
63}
64
65impl Tooltip for StructDecl {
66 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
67 if let Some(ref attributes) = self.attributes {
68 writeln!(f, "{}", attributes)?;
69 }
70
71 write!(f, "{}", self.storage)?;
72 if let Some(ref modifier) = self.storage_modifier {
73 write!(f, "<{}>", modifier)?;
74 }
75
76 write!(f, " {} ", self.name)?;
77
78 Tooltip::fmt(&self.body, f)
79 }
80}
81
82impl Tooltip for StructBody {
83 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
84 writeln!(f, "{{")?;
85
86 for field in self.fields.iter() {
87 if let Decl::Field(ref field) = field {
88 writeln!(f, "\t{}", field)?;
89 }
90 }
91
92 write!(f, "}};")
93 }
94}
95
96impl Tooltip for FieldDecl {
97 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
98 write!(f, "{}", self)
99 }
100}
101
102impl Tooltip for FunctionDecl {
103 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
104 if let Some(ref attributes) = self.attributes {
105 writeln!(f, "{} ", attributes)?;
106 }
107
108 write!(f, "{}", self.storage)?;
109 if let Some(ref modifier) = self.storage_modifier {
110 write!(f, "<{}>", modifier)?;
111 }
112
113 write!(f, " {}(", self.name)?;
114 for (idx, param) in self.params.iter().enumerate() {
115 Tooltip::fmt(param, f)?;
116 if idx < self.params.len() - 1 {
117 write!(f, ", ")?;
118 }
119 }
120 write!(f, ")")?;
121
122 if let Some(ref ty) = self.return_ty {
123 write!(f, " -> {}", ty)?;
124 }
125
126 Ok(())
127 }
128}
129
130impl Tooltip for ParamDecl {
131 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
132 if let Some(ref attributes) = self.attributes {
133 writeln!(f, "{} ", attributes)?;
134 }
135
136 write!(f, "{}: {}", self.name, self.ty)
137 }
138}
139
140impl Tooltip for ExtensionDecl {
141 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
142 write!(f, "TODO")
143 }
144}
145
146impl Tooltip for ImportPathDecl {
147 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
148 write!(f, "{} {}", self.keyword, self.qualified_name())
149 }
150}
151
152impl Tooltip for ModuleDecl {
153 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
154 write!(f, "import {} from {};", self.name, self.path)
155 }
156}