1use std::path::PathBuf;
6
7use serde::{Deserialize, Serialize};
8
9use crate::model::names::{Arity, FunctionName, Mfa, ModuleName, RecordName, TypeName};
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
17pub enum RefContext {
18 Body,
20 TypeAttribute,
23 OtherAttribute,
26 AttributeString,
30}
31
32impl RefContext {
33 #[must_use]
37 pub fn is_attribute(self) -> bool {
38 !matches!(self, Self::Body)
39 }
40
41 #[must_use]
45 pub fn holds_calls(self) -> bool {
46 matches!(self, Self::Body | Self::OtherAttribute)
47 }
48}
49
50#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
51#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
52#[serde(tag = "kind", rename_all = "snake_case")]
53pub enum SymbolKind {
54 Behaviour {
55 module: ModuleName,
56 },
57 Callback {
58 module: ModuleName,
59 function: FunctionName,
60 arity: Arity,
61 },
62 Function {
63 mfa: Mfa,
64 },
65 FunctionAnyArity {
70 module: ModuleName,
71 function: FunctionName,
72 },
73 Macro {
74 name: String,
75 },
76 Record {
77 name: RecordName,
78 },
79 Type {
80 module: ModuleName,
81 name: TypeName,
82 arity: Arity,
83 },
84}
85
86#[derive(
92 Debug, Clone, Copy, Default, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize,
93)]
94#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
95#[serde(rename_all = "snake_case")]
96pub enum RefOrigin {
97 #[default]
98 Added,
99 Context,
100}
101
102impl RefOrigin {
103 #[allow(clippy::trivially_copy_pass_by_ref)]
105 #[must_use]
106 pub fn is_added(&self) -> bool {
107 matches!(self, Self::Added)
108 }
109}
110
111#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
112#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
113pub struct SymbolRef {
114 #[serde(flatten)]
115 pub kind: SymbolKind,
116 #[serde(default, skip_serializing_if = "RefOrigin::is_added")]
117 pub origin: RefOrigin,
118}
119
120impl SymbolRef {
121 pub fn function(mfa: Mfa) -> Self {
122 Self {
123 kind: SymbolKind::Function { mfa },
124 origin: RefOrigin::Added,
125 }
126 }
127
128 pub fn function_any_arity(module: ModuleName, function: FunctionName) -> Self {
129 Self {
130 kind: SymbolKind::FunctionAnyArity { module, function },
131 origin: RefOrigin::Added,
132 }
133 }
134
135 pub fn record(name: RecordName) -> Self {
136 Self {
137 kind: SymbolKind::Record { name },
138 origin: RefOrigin::Added,
139 }
140 }
141
142 pub fn macro_use(name: impl Into<String>) -> Self {
143 Self {
144 kind: SymbolKind::Macro { name: name.into() },
145 origin: RefOrigin::Added,
146 }
147 }
148
149 pub fn type_ref(module: ModuleName, name: TypeName, arity: Arity) -> Self {
150 Self {
151 kind: SymbolKind::Type {
152 module,
153 name,
154 arity,
155 },
156 origin: RefOrigin::Added,
157 }
158 }
159
160 #[must_use]
161 pub fn with_origin(mut self, origin: RefOrigin) -> Self {
162 self.origin = origin;
163 self
164 }
165}
166
167#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
168#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
169pub struct Reference {
170 pub symbol: SymbolRef,
171 pub from_path: PathBuf,
172 pub line: usize,
173}