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,
21 TypeAttribute,
24}
25
26#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
27#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
28#[serde(tag = "kind", rename_all = "snake_case")]
29pub enum SymbolKind {
30 Behaviour {
31 module: ModuleName,
32 },
33 Callback {
34 module: ModuleName,
35 function: FunctionName,
36 arity: Arity,
37 },
38 Function {
39 mfa: Mfa,
40 },
41 FunctionAnyArity {
46 module: ModuleName,
47 function: FunctionName,
48 },
49 Macro {
50 name: String,
51 },
52 Record {
53 name: RecordName,
54 },
55 Type {
56 module: ModuleName,
57 name: TypeName,
58 arity: Arity,
59 },
60}
61
62#[derive(
68 Debug, Clone, Copy, Default, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize,
69)]
70#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
71#[serde(rename_all = "snake_case")]
72pub enum RefOrigin {
73 #[default]
74 Added,
75 Context,
76}
77
78impl RefOrigin {
79 #[allow(clippy::trivially_copy_pass_by_ref)]
81 #[must_use]
82 pub fn is_added(&self) -> bool {
83 matches!(self, Self::Added)
84 }
85}
86
87#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
88#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
89pub struct SymbolRef {
90 #[serde(flatten)]
91 pub kind: SymbolKind,
92 #[serde(default, skip_serializing_if = "RefOrigin::is_added")]
93 pub origin: RefOrigin,
94}
95
96impl SymbolRef {
97 pub fn function(mfa: Mfa) -> Self {
98 Self {
99 kind: SymbolKind::Function { mfa },
100 origin: RefOrigin::Added,
101 }
102 }
103
104 pub fn function_any_arity(module: ModuleName, function: FunctionName) -> Self {
105 Self {
106 kind: SymbolKind::FunctionAnyArity { module, function },
107 origin: RefOrigin::Added,
108 }
109 }
110
111 pub fn record(name: RecordName) -> Self {
112 Self {
113 kind: SymbolKind::Record { name },
114 origin: RefOrigin::Added,
115 }
116 }
117
118 pub fn macro_use(name: impl Into<String>) -> Self {
119 Self {
120 kind: SymbolKind::Macro { name: name.into() },
121 origin: RefOrigin::Added,
122 }
123 }
124
125 pub fn type_ref(module: ModuleName, name: TypeName, arity: Arity) -> Self {
126 Self {
127 kind: SymbolKind::Type {
128 module,
129 name,
130 arity,
131 },
132 origin: RefOrigin::Added,
133 }
134 }
135
136 #[must_use]
137 pub fn with_origin(mut self, origin: RefOrigin) -> Self {
138 self.origin = origin;
139 self
140 }
141}
142
143#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
144#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
145pub struct Reference {
146 pub symbol: SymbolRef,
147 pub from_path: PathBuf,
148 pub line: usize,
149}