Skip to main content

mir_types/
display.rs

1use std::fmt;
2
3use crate::atomic::Atomic;
4use crate::union::Union;
5
6impl fmt::Display for Union {
7    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8        if self.types.is_empty() {
9            return write!(f, "never");
10        }
11        let strs: Vec<String> = self.types.iter().map(|a| format!("{}", a)).collect();
12        write!(f, "{}", strs.join("|"))
13    }
14}
15
16impl fmt::Display for Atomic {
17    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18        match self {
19            Atomic::TString => write!(f, "string"),
20            Atomic::TLiteralString(s) => write!(f, "\"{}\"", s),
21            Atomic::TClassString(None) => write!(f, "class-string"),
22            Atomic::TClassString(Some(cls)) => write!(f, "class-string<{}>", cls),
23            Atomic::TNonEmptyString => write!(f, "non-empty-string"),
24            Atomic::TNumericString => write!(f, "numeric-string"),
25
26            Atomic::TInt => write!(f, "int"),
27            Atomic::TLiteralInt(n) => write!(f, "{}", n),
28            Atomic::TIntRange { min, max } => {
29                let lo = min
30                    .map(|n| n.to_string())
31                    .unwrap_or_else(|| "min".to_string());
32                let hi = max
33                    .map(|n| n.to_string())
34                    .unwrap_or_else(|| "max".to_string());
35                write!(f, "int<{}, {}>", lo, hi)
36            }
37            Atomic::TPositiveInt => write!(f, "positive-int"),
38            Atomic::TNegativeInt => write!(f, "negative-int"),
39            Atomic::TNonNegativeInt => write!(f, "non-negative-int"),
40
41            Atomic::TFloat => write!(f, "float"),
42            Atomic::TLiteralFloat(i, frac) => write!(f, "{}.{}", i, frac),
43
44            Atomic::TBool => write!(f, "bool"),
45            Atomic::TTrue => write!(f, "true"),
46            Atomic::TFalse => write!(f, "false"),
47
48            Atomic::TNull => write!(f, "null"),
49            Atomic::TVoid => write!(f, "void"),
50            Atomic::TNever => write!(f, "never"),
51            Atomic::TMixed => write!(f, "mixed"),
52            Atomic::TScalar => write!(f, "scalar"),
53            Atomic::TNumeric => write!(f, "numeric"),
54
55            Atomic::TObject => write!(f, "object"),
56            Atomic::TNamedObject { fqcn, type_params } => {
57                if type_params.is_empty() {
58                    write!(f, "{}", fqcn)
59                } else {
60                    let params: Vec<String> =
61                        type_params.iter().map(|p| format!("{}", p)).collect();
62                    write!(f, "{}<{}>", fqcn, params.join(", "))
63                }
64            }
65            Atomic::TStaticObject { fqcn } => write!(f, "static({})", fqcn),
66            Atomic::TSelf { fqcn } => write!(f, "self({})", fqcn),
67            Atomic::TParent { fqcn } => write!(f, "parent({})", fqcn),
68
69            Atomic::TCallable {
70                params: None,
71                return_type: None,
72            } => write!(f, "callable"),
73            Atomic::TCallable {
74                params: Some(params),
75                return_type,
76            } => {
77                let ps: Vec<String> = params
78                    .iter()
79                    .map(|p| {
80                        if let Some(ty) = &p.ty {
81                            format!("{}", ty)
82                        } else {
83                            "mixed".to_string()
84                        }
85                    })
86                    .collect();
87                let ret = return_type
88                    .as_ref()
89                    .map(|r| format!("{}", r))
90                    .unwrap_or_else(|| "mixed".to_string());
91                write!(f, "callable({}): {}", ps.join(", "), ret)
92            }
93            Atomic::TCallable {
94                params: None,
95                return_type: Some(ret),
96            } => {
97                write!(f, "callable(): {}", ret)
98            }
99            Atomic::TClosure {
100                params,
101                return_type,
102                ..
103            } => {
104                let ps: Vec<String> = params
105                    .iter()
106                    .map(|p| {
107                        if let Some(ty) = &p.ty {
108                            format!("{}", ty)
109                        } else {
110                            "mixed".to_string()
111                        }
112                    })
113                    .collect();
114                write!(f, "Closure({}): {}", ps.join(", "), return_type)
115            }
116
117            Atomic::TArray { key, value } => {
118                write!(f, "array<{}, {}>", key, value)
119            }
120            Atomic::TList { value } => write!(f, "list<{}>", value),
121            Atomic::TNonEmptyArray { key, value } => {
122                write!(f, "non-empty-array<{}, {}>", key, value)
123            }
124            Atomic::TNonEmptyList { value } => write!(f, "non-empty-list<{}>", value),
125            Atomic::TKeyedArray { properties, .. } => {
126                let entries: Vec<String> = properties
127                    .iter()
128                    .map(|(k, v)| {
129                        let key_str = match k {
130                            crate::atomic::ArrayKey::String(s) => format!("'{}'", s),
131                            crate::atomic::ArrayKey::Int(n) => n.to_string(),
132                        };
133                        let opt = if v.optional { "?" } else { "" };
134                        format!("{}{}: {}", key_str, opt, v.ty)
135                    })
136                    .collect();
137                write!(f, "array{{{}}}", entries.join(", "))
138            }
139
140            Atomic::TTemplateParam { name, .. } => write!(f, "{}", name),
141            Atomic::TConditional {
142                subject,
143                if_true,
144                if_false,
145            } => {
146                write!(f, "({} is ? {} : {})", subject, if_true, if_false)
147            }
148
149            Atomic::TInterfaceString => write!(f, "interface-string"),
150            Atomic::TEnumString => write!(f, "enum-string"),
151            Atomic::TTraitString => write!(f, "trait-string"),
152        }
153    }
154}