1use rustc_hash::FxHashMap as HashMap;
2
3use ecow::EcoString;
4
5use crate::ast::{
6 Annotation, EnumVariant, Generic, Literal, Span, StructFieldDefinition, StructKind,
7};
8use crate::types::Type;
9
10#[derive(Debug, Clone)]
11pub struct Definition {
12 pub visibility: Visibility,
13 pub ty: Type,
14 pub name: Option<EcoString>,
15 pub name_span: Option<Span>,
16 pub doc: Option<String>,
17 pub body: DefinitionBody,
18}
19
20#[derive(Debug, Clone)]
21pub enum DefinitionBody {
22 TypeAlias {
23 generics: Vec<Generic>,
24 annotation: Annotation,
25 methods: MethodSignatures,
26 },
27 Enum {
28 generics: Vec<Generic>,
29 variants: Vec<EnumVariant>,
30 methods: MethodSignatures,
31 display: bool,
32 },
33 Struct {
34 generics: Vec<Generic>,
35 fields: Vec<StructFieldDefinition>,
36 kind: StructKind,
37 methods: MethodSignatures,
38 constructor: Option<Type>,
39 display: bool,
40 closed_domain: bool,
41 },
42 Interface {
43 definition: Interface,
44 },
45 Value {
46 allowed_lints: Vec<String>,
47 go_hints: Vec<String>,
48 go_name: Option<String>,
49 const_value: Option<Literal>,
53 },
54}
55
56impl Definition {
57 pub fn ty(&self) -> &Type {
58 &self.ty
59 }
60
61 pub fn visibility(&self) -> &Visibility {
62 &self.visibility
63 }
64
65 pub fn name_span(&self) -> Option<Span> {
66 self.name_span
67 }
68
69 pub fn doc(&self) -> Option<&String> {
70 self.doc.as_ref()
71 }
72
73 pub fn is_newtype(&self) -> bool {
78 matches!(
79 &self.body,
80 DefinitionBody::Struct {
81 kind: StructKind::Tuple,
82 fields,
83 generics,
84 ..
85 } if fields.len() == 1 && generics.is_empty()
86 )
87 }
88
89 pub fn is_pointer_backed_newtype<F>(&self, is_alias: F) -> bool
90 where
91 F: Fn(&str) -> bool,
92 {
93 self.is_newtype()
94 && matches!(
95 &self.body,
96 DefinitionBody::Struct { fields, .. }
97 if crate::types::peel_alias(&fields[0].ty, is_alias).is_ref()
98 )
99 }
100
101 pub fn allowed_lints(&self) -> &[String] {
102 match &self.body {
103 DefinitionBody::Value { allowed_lints, .. } => allowed_lints,
104 _ => &[],
105 }
106 }
107
108 pub fn go_hints(&self) -> &[String] {
109 match &self.body {
110 DefinitionBody::Value { go_hints, .. } => go_hints,
111 _ => &[],
112 }
113 }
114
115 pub fn go_name(&self) -> Option<&str> {
116 match &self.body {
117 DefinitionBody::Value { go_name, .. } => go_name.as_deref(),
118 _ => None,
119 }
120 }
121
122 pub fn const_value(&self) -> Option<&Literal> {
123 match &self.body {
124 DefinitionBody::Value { const_value, .. } => const_value.as_ref(),
125 _ => None,
126 }
127 }
128
129 pub fn methods_mut(&mut self) -> Option<&mut MethodSignatures> {
130 match &mut self.body {
131 DefinitionBody::Struct { methods, .. } => Some(methods),
132 DefinitionBody::TypeAlias { methods, .. } => Some(methods),
133 DefinitionBody::Enum { methods, .. } => Some(methods),
134 _ => None,
135 }
136 }
137
138 pub fn is_display(&self) -> bool {
139 matches!(
140 &self.body,
141 DefinitionBody::Struct { display: true, .. }
142 | DefinitionBody::Enum { display: true, .. }
143 )
144 }
145
146 pub fn is_closed_domain(&self) -> bool {
147 matches!(
148 &self.body,
149 DefinitionBody::Struct {
150 closed_domain: true,
151 ..
152 }
153 )
154 }
155
156 pub fn is_type_definition(&self) -> bool {
157 matches!(
158 self.body,
159 DefinitionBody::Struct { .. }
160 | DefinitionBody::Enum { .. }
161 | DefinitionBody::TypeAlias { .. }
162 )
163 }
164
165 pub fn is_type_alias(&self) -> bool {
166 matches!(self.body, DefinitionBody::TypeAlias { .. })
167 }
168
169 pub fn is_value(&self, qualified_name: &str) -> bool {
170 matches!(self.body, DefinitionBody::Value { .. })
171 && self.ty.unwrap_forall().get_qualified_id() != Some(qualified_name)
172 }
173}
174
175pub type MethodSignatures = HashMap<EcoString, Type>;
176
177#[derive(Debug, Clone, PartialEq)]
178pub enum Visibility {
179 Public,
180 Private,
181 Local,
182}
183
184impl Visibility {
185 pub fn is_public(&self) -> bool {
186 matches!(self, Visibility::Public)
187 }
188}
189
190#[derive(Debug, Clone, PartialEq)]
191pub struct Interface {
192 pub name: EcoString,
193 pub generics: Vec<Generic>,
194 pub parents: Vec<Type>,
195 pub methods: HashMap<EcoString, Type>,
196}