1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
4#[serde(rename_all = "PascalCase")]
5pub enum SymbolKind {
6 File,
7 Module,
8 Namespace,
9 Package,
10 Class,
11 Method,
12 Property,
13 Field,
14 Constructor,
15 Enum,
16 Interface,
17 Function,
18 Variable,
19 Constant,
20 String,
21 Number,
22 Boolean,
23 Array,
24 Object,
25 Key,
26 Null,
27 EnumMember,
28 Struct,
29 Event,
30 Operator,
31 TypeParameter,
32}
33
34impl SymbolKind {
35 pub fn from_lsp(kind: lsp_types::SymbolKind) -> Self {
36 match kind {
37 lsp_types::SymbolKind::FILE => SymbolKind::File,
38 lsp_types::SymbolKind::MODULE => SymbolKind::Module,
39 lsp_types::SymbolKind::NAMESPACE => SymbolKind::Namespace,
40 lsp_types::SymbolKind::PACKAGE => SymbolKind::Package,
41 lsp_types::SymbolKind::CLASS => SymbolKind::Class,
42 lsp_types::SymbolKind::METHOD => SymbolKind::Method,
43 lsp_types::SymbolKind::PROPERTY => SymbolKind::Property,
44 lsp_types::SymbolKind::FIELD => SymbolKind::Field,
45 lsp_types::SymbolKind::CONSTRUCTOR => SymbolKind::Constructor,
46 lsp_types::SymbolKind::ENUM => SymbolKind::Enum,
47 lsp_types::SymbolKind::INTERFACE => SymbolKind::Interface,
48 lsp_types::SymbolKind::FUNCTION => SymbolKind::Function,
49 lsp_types::SymbolKind::VARIABLE => SymbolKind::Variable,
50 lsp_types::SymbolKind::CONSTANT => SymbolKind::Constant,
51 lsp_types::SymbolKind::STRING => SymbolKind::String,
52 lsp_types::SymbolKind::NUMBER => SymbolKind::Number,
53 lsp_types::SymbolKind::BOOLEAN => SymbolKind::Boolean,
54 lsp_types::SymbolKind::ARRAY => SymbolKind::Array,
55 lsp_types::SymbolKind::OBJECT => SymbolKind::Object,
56 lsp_types::SymbolKind::KEY => SymbolKind::Key,
57 lsp_types::SymbolKind::NULL => SymbolKind::Null,
58 lsp_types::SymbolKind::ENUM_MEMBER => SymbolKind::EnumMember,
59 lsp_types::SymbolKind::STRUCT => SymbolKind::Struct,
60 lsp_types::SymbolKind::EVENT => SymbolKind::Event,
61 lsp_types::SymbolKind::OPERATOR => SymbolKind::Operator,
62 lsp_types::SymbolKind::TYPE_PARAMETER => SymbolKind::TypeParameter,
63 _ => SymbolKind::Variable,
64 }
65 }
66
67 pub fn as_str(&self) -> &'static str {
68 match self {
69 SymbolKind::File => "File",
70 SymbolKind::Module => "Module",
71 SymbolKind::Namespace => "Namespace",
72 SymbolKind::Package => "Package",
73 SymbolKind::Class => "Class",
74 SymbolKind::Method => "Method",
75 SymbolKind::Property => "Property",
76 SymbolKind::Field => "Field",
77 SymbolKind::Constructor => "Constructor",
78 SymbolKind::Enum => "Enum",
79 SymbolKind::Interface => "Interface",
80 SymbolKind::Function => "Function",
81 SymbolKind::Variable => "Variable",
82 SymbolKind::Constant => "Constant",
83 SymbolKind::String => "String",
84 SymbolKind::Number => "Number",
85 SymbolKind::Boolean => "Boolean",
86 SymbolKind::Array => "Array",
87 SymbolKind::Object => "Object",
88 SymbolKind::Key => "Key",
89 SymbolKind::Null => "Null",
90 SymbolKind::EnumMember => "EnumMember",
91 SymbolKind::Struct => "Struct",
92 SymbolKind::Event => "Event",
93 SymbolKind::Operator => "Operator",
94 SymbolKind::TypeParameter => "TypeParameter",
95 }
96 }
97}
98
99impl std::fmt::Display for SymbolKind {
100 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
101 write!(f, "{}", self.as_str())
102 }
103}
104
105impl std::str::FromStr for SymbolKind {
106 type Err = String;
107
108 fn from_str(s: &str) -> Result<Self, Self::Err> {
109 match s.to_lowercase().as_str() {
110 "file" => Ok(SymbolKind::File),
111 "module" => Ok(SymbolKind::Module),
112 "namespace" => Ok(SymbolKind::Namespace),
113 "package" => Ok(SymbolKind::Package),
114 "class" => Ok(SymbolKind::Class),
115 "method" => Ok(SymbolKind::Method),
116 "property" => Ok(SymbolKind::Property),
117 "field" => Ok(SymbolKind::Field),
118 "constructor" => Ok(SymbolKind::Constructor),
119 "enum" => Ok(SymbolKind::Enum),
120 "interface" => Ok(SymbolKind::Interface),
121 "function" => Ok(SymbolKind::Function),
122 "variable" => Ok(SymbolKind::Variable),
123 "constant" => Ok(SymbolKind::Constant),
124 "string" => Ok(SymbolKind::String),
125 "number" => Ok(SymbolKind::Number),
126 "boolean" => Ok(SymbolKind::Boolean),
127 "array" => Ok(SymbolKind::Array),
128 "object" => Ok(SymbolKind::Object),
129 "key" => Ok(SymbolKind::Key),
130 "null" => Ok(SymbolKind::Null),
131 "enummember" => Ok(SymbolKind::EnumMember),
132 "struct" => Ok(SymbolKind::Struct),
133 "event" => Ok(SymbolKind::Event),
134 "operator" => Ok(SymbolKind::Operator),
135 "typeparameter" => Ok(SymbolKind::TypeParameter),
136 _ => Err(format!("Unknown symbol kind: {}", s)),
137 }
138 }
139}
140
141#[derive(Debug, Clone, Serialize, Deserialize)]
142pub struct SymbolInfo {
143 pub name: String,
144 pub kind: String,
145 pub path: String,
146 pub line: u32,
147 #[serde(default)]
148 pub column: u32,
149 #[serde(skip_serializing_if = "Option::is_none")]
150 pub container: Option<String>,
151 #[serde(skip_serializing_if = "Option::is_none")]
152 pub detail: Option<String>,
153 #[serde(skip_serializing_if = "Option::is_none")]
154 pub documentation: Option<String>,
155 #[serde(skip_serializing_if = "Option::is_none")]
156 pub range_start_line: Option<u32>,
157 #[serde(skip_serializing_if = "Option::is_none")]
158 pub range_end_line: Option<u32>,
159 #[serde(skip_serializing_if = "Option::is_none", rename = "ref")]
160 pub reference: Option<String>,
161}
162
163impl SymbolInfo {
164 pub fn new(name: String, kind: SymbolKind, path: String, line: u32) -> Self {
165 Self {
166 name,
167 kind: kind.to_string(),
168 path,
169 line,
170 column: 0,
171 container: None,
172 detail: None,
173 documentation: None,
174 range_start_line: None,
175 range_end_line: None,
176 reference: None,
177 }
178 }
179}