use crate::{Language, LanguageSymbols};
use tree_sitter::Node;
pub struct Toml;
impl Language for Toml {
fn name(&self) -> &'static str {
"TOML"
}
fn extensions(&self) -> &'static [&'static str] {
&["toml"]
}
fn grammar_name(&self) -> &'static str {
"toml"
}
fn as_symbols(&self) -> Option<&dyn LanguageSymbols> {
Some(self)
}
fn node_name<'a>(&self, node: &Node, content: &'a str) -> Option<&'a str> {
match node.kind() {
"table" | "array_table" | "table_array_element" => {
let mut cursor = node.walk();
for child in node.children(&mut cursor) {
if child.kind() == "bare_key" || child.kind() == "quoted_key" {
return Some(&content[child.byte_range()]);
}
}
None
}
"pair" => {
if is_inside_inline_table(node) {
return None;
}
let mut cursor = node.walk();
for child in node.children(&mut cursor) {
if child.kind() == "bare_key" || child.kind() == "quoted_key" {
return Some(&content[child.byte_range()]);
}
}
None
}
_ => None,
}
}
fn build_signature(&self, node: &Node, content: &str) -> String {
if let Some(key) = self.node_name(node, content) {
match node.kind() {
"table" | "array_table" | "table_array_element" => {
let brackets = if node.kind() == "table_array_element" {
("[[", "]]")
} else {
("[", "]")
};
return format!("{}{}{}", brackets.0, key, brackets.1);
}
"pair" => {
let mut cursor = node.walk();
for child in node.children(&mut cursor) {
let k = child.kind();
if k != "bare_key" && k != "quoted_key" && k != "=" {
let val_text = &content[child.byte_range()];
if val_text.len() > 40 {
return format!("{} = {}…", key, &val_text[..37]);
}
return format!("{} = {}", key, val_text);
}
}
return key.to_string();
}
_ => {}
}
}
content[node.byte_range()]
.lines()
.next()
.unwrap_or("")
.trim()
.to_string()
}
}
impl LanguageSymbols for Toml {}
fn is_inside_inline_table(node: &Node) -> bool {
let mut current = node.parent();
while let Some(n) = current {
if n.kind() == "inline_table" {
return true;
}
current = n.parent();
}
false
}
#[cfg(test)]
mod tests {
use super::*;
use crate::validate_unused_kinds_audit;
#[test]
fn unused_node_kinds_audit() {
let documented_unused: &[&str] = &[];
validate_unused_kinds_audit(&Toml, documented_unused)
.expect("TOML unused node kinds audit failed");
}
}