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
43#[derive(Debug, PartialEq, Clone)]
44pub struct ExprDef {
45 pub value: Box<Expr>,
46
47 pub constant: bool,
48 pub ty: Option<Ty>,
49}
50
51#[derive(Debug, PartialEq, Clone)]
52pub struct TyDef {
53 pub ty: Ty,
54 pub is_framed: bool,
55 pub framed_label: Option<String>,
56}
57
58#[derive(Debug, PartialEq, Clone)]
59pub struct ImportDef {
60 pub kind: ImportKind,
61 pub span: Span,
62}
63
64#[derive(Debug, PartialEq, Clone)]
65pub enum ImportKind {
66 Single(Path, Option<String>),
68
69 Many(Path, Vec<ImportDef>),
71}
72
73impl ImportDef {
74 pub fn new_simple(path: Path, span: Span) -> Self {
75 Self {
76 kind: ImportKind::Single(path, None),
77 span,
78 }
79 }
80
81 pub fn as_simple(&self) -> Option<&Path> {
82 let ImportKind::Single(path, _) = &self.kind else {
83 return None;
84 };
85 Some(path)
86 }
87
88 pub fn path(&self) -> &Path {
89 match &self.kind {
90 ImportKind::Single(path, _) => path,
91 ImportKind::Many(path, _) => path,
92 }
93 }
94}
95
96#[derive(Debug, Clone, PartialEq)]
97pub struct Annotation {
98 pub expr: Box<Expr>,
99}
100
101#[derive(Debug, Clone, PartialEq)]
102pub struct DocComment {
103 pub content: String,
104 pub span: Span,
105}
106
107impl Def {
108 pub fn new<K: Into<DefKind>>(kind: K) -> Def {
109 Def {
110 kind: kind.into(),
111 annotations: Vec::new(),
112 doc_comment: None,
113
114 span: None,
115 span_name: None,
116 }
117 }
118}
119
120impl From<ModuleDef> for DefKind {
121 fn from(value: ModuleDef) -> Self {
122 DefKind::Module(value)
123 }
124}
125impl From<Expr> for DefKind {
126 fn from(expr: Expr) -> Self {
127 DefKind::Expr(ExprDef {
128 value: Box::new(expr),
129 ty: None,
130 constant: false,
131 })
132 }
133}
134
135impl std::fmt::Debug for ModuleDef {
136 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
137 let mut ds = f.debug_struct("ModuleDef");
138
139 if self.defs.len() < 15 {
140 ds.field("defs", &DebugNames(&self.defs));
141 } else {
142 ds.field("defs", &format!("... {} entries ...", self.defs.len()));
143 }
144 ds.finish()
145 }
146}
147
148struct DebugNames<'a>(&'a IndexMap<String, Def>);
149
150impl<'a> std::fmt::Debug for DebugNames<'a> {
151 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
152 let mut dm = f.debug_map();
153 for (n, def) in self.0.iter().sorted_by_key(|x| x.0) {
154 dm.entry(n, def);
155 }
156 dm.finish()
157 }
158}