lisette_syntax/
display.rs1use std::fmt;
2
3use crate::types::Type;
4
5impl Type {
6 pub fn stringify(&self) -> String {
7 match self {
8 Type::Nominal {
9 id, params: args, ..
10 } => {
11 let args_formatted = args
12 .iter()
13 .map(|a| a.stringify())
14 .collect::<Vec<_>>()
15 .join(", ");
16
17 let name = id.last_segment();
18
19 if name == "Unit" {
20 return "()".to_string();
21 }
22
23 if name == "bool" {
24 return "bool".to_string();
25 }
26
27 if name.starts_with("Tuple") {
28 return format!("({})", args_formatted);
29 }
30
31 if name == "Ref" {
32 return format!("Ref<{}>", args_formatted);
33 }
34
35 if args.is_empty() {
36 return name.to_string();
37 }
38
39 format!("{}<{}>", name, args_formatted)
40 }
41
42 Type::Var { id, hint } => match hint {
43 Some(name) => format!("?{}", name),
44 None => format!("?{}", id.as_u32()),
45 },
46
47 Type::Function {
48 params: args,
49 param_mutability,
50 return_type,
51 ..
52 } => {
53 let args_formatted = args
54 .iter()
55 .enumerate()
56 .map(|(i, a)| {
57 let is_mut = param_mutability.get(i).copied().unwrap_or(false);
58 if is_mut {
59 format!("mut {}", a.stringify())
60 } else {
61 a.stringify()
62 }
63 })
64 .collect::<Vec<_>>()
65 .join(", ");
66
67 let ret_formatted = (*return_type).stringify();
68
69 format!("fn ({}) -> {}", args_formatted, ret_formatted)
70 }
71
72 Type::Forall { .. } => {
73 unreachable!("Forall types are always instantiated before display")
74 }
75
76 Type::Parameter(name) => name.to_string(),
77
78 Type::Never => "Never".to_string(),
79
80 Type::Tuple(elements) => {
81 let formatted = elements
82 .iter()
83 .map(|e| e.stringify())
84 .collect::<Vec<_>>()
85 .join(", ");
86 format!("({})", formatted)
87 }
88
89 Type::Error => "<error>".to_string(),
90
91 Type::ImportNamespace(module_id) => {
92 let path = module_id.strip_prefix("go:").unwrap_or(module_id);
93 path.rsplit('/').next().unwrap_or(module_id).to_string()
94 }
95
96 Type::ReceiverPlaceholder => "self".to_string(),
97
98 Type::Simple(kind) => match kind {
99 crate::types::SimpleKind::Unit => "()".to_string(),
100 _ => kind.leaf_name().to_string(),
101 },
102
103 Type::Compound { kind, args } => {
104 let args_formatted = args
105 .iter()
106 .map(|a| a.stringify())
107 .collect::<Vec<_>>()
108 .join(", ");
109 if args.is_empty() {
110 kind.leaf_name().to_string()
111 } else {
112 format!("{}<{}>", kind.leaf_name(), args_formatted)
113 }
114 }
115 }
116 }
117}
118
119impl fmt::Display for Type {
120 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
121 let (types, _generics) = Self::remove_vars(&[self]);
122 write!(f, "{}", types[0].stringify())
123 }
124}