1use enum_as_inner::EnumAsInner;
2use indexmap::IndexMap;
3use itertools::Itertools;
4
5use crate::Span;
6use crate::pr::path::Path;
7use crate::pr::{Expr, Ty};
8
9#[derive(Debug, Clone, PartialEq)]
11pub struct Def {
12 pub kind: DefKind,
13
14 pub annotations: Vec<Annotation>,
15
16 pub doc_comment: Option<DocComment>,
17
18 pub span: Option<Span>,
20
21 pub span_name: Option<Span>,
23}
24
25#[derive(Debug, EnumAsInner, PartialEq, Clone)]
26pub enum DefKind {
27 Module(ModuleDef),
28 Expr(ExprDef),
29 Ty(TyDef),
30 Import(ImportDef),
31
32 Unresolved(Option<Box<DefKind>>),
36}
37
38#[derive(PartialEq, Clone, Default)]
39pub struct ModuleDef {
40 pub defs: IndexMap<String, Def>,
41
42 pub annotations: Vec<Annotation>,
44
45 pub span_content: Option<Span>,
49}
50
51#[derive(Debug, PartialEq, Clone)]
52pub struct ExprDef {
53 pub value: Box<Expr>,
54
55 pub constant: bool,
56 pub ty: Option<Ty>,
57}
58
59#[derive(Debug, PartialEq, Clone)]
60pub struct TyDef {
61 pub ty: Ty,
62 pub is_framed: bool,
63 pub framed_label: Option<String>,
64}
65
66#[derive(Debug, PartialEq, Clone)]
67pub struct ImportDef {
68 pub kind: ImportKind,
69 pub span: Span,
70}
71
72#[derive(Debug, PartialEq, Clone)]
73pub enum ImportKind {
74 Single(Path, Option<String>),
76
77 Many(Path, Vec<ImportDef>),
79}
80
81impl ImportDef {
82 pub fn new_simple(path: Path, span: Span) -> Self {
83 Self {
84 kind: ImportKind::Single(path, None),
85 span,
86 }
87 }
88
89 pub fn as_simple(&self) -> Option<&Path> {
90 let ImportKind::Single(path, _) = &self.kind else {
91 return None;
92 };
93 Some(path)
94 }
95
96 pub fn path(&self) -> &Path {
97 match &self.kind {
98 ImportKind::Single(path, _) => path,
99 ImportKind::Many(path, _) => path,
100 }
101 }
102}
103
104#[derive(Debug, Clone, PartialEq)]
105pub struct Annotation {
106 pub expr: Box<Expr>,
107}
108
109#[derive(Debug, Clone, PartialEq)]
110pub struct DocComment {
111 pub content: String,
112 pub span: Span,
113}
114
115impl Def {
116 pub fn new<K: Into<DefKind>>(kind: K) -> Def {
117 Def {
118 kind: kind.into(),
119 annotations: Vec::new(),
120 doc_comment: None,
121
122 span: None,
123 span_name: None,
124 }
125 }
126}
127
128impl From<ModuleDef> for DefKind {
129 fn from(value: ModuleDef) -> Self {
130 DefKind::Module(value)
131 }
132}
133impl From<Expr> for DefKind {
134 fn from(expr: Expr) -> Self {
135 DefKind::Expr(ExprDef {
136 value: Box::new(expr),
137 ty: None,
138 constant: false,
139 })
140 }
141}
142
143impl std::fmt::Debug for ModuleDef {
144 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
145 let mut ds = f.debug_struct("ModuleDef");
146
147 if !self.annotations.is_empty() {
148 ds.field("annotations", &self.annotations);
149 }
150
151 if self.defs.len() < 15 {
152 ds.field("defs", &DebugNames(&self.defs));
153 } else {
154 ds.field("defs", &format!("... {} entries ...", self.defs.len()));
155 }
156 ds.finish()
157 }
158}
159
160struct DebugNames<'a>(&'a IndexMap<String, Def>);
161
162impl<'a> std::fmt::Debug for DebugNames<'a> {
163 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
164 let mut dm = f.debug_map();
165 for (n, def) in self.0.iter().sorted_by_key(|x| x.0) {
166 dm.entry(n, def);
167 }
168 dm.finish()
169 }
170}