normalize_languages/
toml.rs1use crate::{Language, LanguageSymbols};
4use tree_sitter::Node;
5
6pub struct Toml;
8
9impl Language for Toml {
10 fn name(&self) -> &'static str {
11 "TOML"
12 }
13 fn extensions(&self) -> &'static [&'static str] {
14 &["toml"]
15 }
16 fn grammar_name(&self) -> &'static str {
17 "toml"
18 }
19
20 fn as_symbols(&self) -> Option<&dyn LanguageSymbols> {
21 Some(self)
22 }
23
24 fn node_name<'a>(&self, node: &Node, content: &'a str) -> Option<&'a str> {
25 match node.kind() {
26 "table" | "array_table" | "table_array_element" => {
27 let mut cursor = node.walk();
29 for child in node.children(&mut cursor) {
30 if child.kind() == "bare_key" || child.kind() == "quoted_key" {
31 return Some(&content[child.byte_range()]);
32 }
33 }
34 None
35 }
36 "pair" => {
37 if is_inside_inline_table(node) {
39 return None;
40 }
41 let mut cursor = node.walk();
42 for child in node.children(&mut cursor) {
43 if child.kind() == "bare_key" || child.kind() == "quoted_key" {
44 return Some(&content[child.byte_range()]);
45 }
46 }
47 None
48 }
49 _ => None,
50 }
51 }
52
53 fn build_signature(&self, node: &Node, content: &str) -> String {
54 if let Some(key) = self.node_name(node, content) {
55 match node.kind() {
56 "table" | "array_table" | "table_array_element" => {
57 let brackets = if node.kind() == "table_array_element" {
58 ("[[", "]]")
59 } else {
60 ("[", "]")
61 };
62 return format!("{}{}{}", brackets.0, key, brackets.1);
63 }
64 "pair" => {
65 let mut cursor = node.walk();
67 for child in node.children(&mut cursor) {
68 let k = child.kind();
69 if k != "bare_key" && k != "quoted_key" && k != "=" {
70 let val_text = &content[child.byte_range()];
71 if val_text.len() > 40 {
72 return format!("{} = {}…", key, &val_text[..37]);
73 }
74 return format!("{} = {}", key, val_text);
75 }
76 }
77 return key.to_string();
78 }
79 _ => {}
80 }
81 }
82 content[node.byte_range()]
83 .lines()
84 .next()
85 .unwrap_or("")
86 .trim()
87 .to_string()
88 }
89}
90
91impl LanguageSymbols for Toml {}
92
93fn is_inside_inline_table(node: &Node) -> bool {
95 let mut current = node.parent();
96 while let Some(n) = current {
97 if n.kind() == "inline_table" {
98 return true;
99 }
100 current = n.parent();
101 }
102 false
103}
104
105#[cfg(test)]
106mod tests {
107 use super::*;
108 use crate::validate_unused_kinds_audit;
109
110 #[test]
111 fn unused_node_kinds_audit() {
112 let documented_unused: &[&str] = &[];
114 validate_unused_kinds_audit(&Toml, documented_unused)
115 .expect("TOML unused node kinds audit failed");
116 }
117}