codelens_core/language/
definition.rs1use serde::Deserialize;
4
5#[derive(Debug, Clone, Deserialize)]
7pub struct Language {
8 pub name: String,
10
11 #[serde(default)]
13 pub extensions: Vec<String>,
14
15 #[serde(default)]
17 pub filenames: Vec<String>,
18
19 #[serde(default)]
21 pub line_comments: Vec<String>,
22
23 #[serde(default, deserialize_with = "deserialize_block_comments")]
25 pub block_comments: Vec<(String, String)>,
26
27 #[serde(default)]
29 pub string_delimiters: Vec<StringDelimiter>,
30
31 #[serde(default)]
33 pub function_pattern: Option<String>,
34
35 #[serde(default)]
37 pub complexity_keywords: Vec<String>,
38
39 #[serde(default)]
41 pub nested_comments: bool,
42}
43
44impl Default for Language {
45 fn default() -> Self {
46 Self {
47 name: "Unknown".to_string(),
48 extensions: vec![],
49 filenames: vec![],
50 line_comments: vec![],
51 block_comments: vec![],
52 string_delimiters: vec![],
53 function_pattern: None,
54 complexity_keywords: vec![],
55 nested_comments: false,
56 }
57 }
58}
59
60#[derive(Debug, Clone, Deserialize)]
62pub struct StringDelimiter {
63 pub start: String,
65 pub end: String,
67 #[serde(default)]
69 pub escape: Option<String>,
70}
71
72fn deserialize_block_comments<'de, D>(deserializer: D) -> Result<Vec<(String, String)>, D::Error>
74where
75 D: serde::Deserializer<'de>,
76{
77 let raw: Vec<Vec<String>> = Vec::deserialize(deserializer)?;
78 Ok(raw
79 .into_iter()
80 .filter_map(|pair| {
81 if pair.len() >= 2 {
82 Some((pair[0].clone(), pair[1].clone()))
83 } else {
84 None
85 }
86 })
87 .collect())
88}
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93
94 #[test]
95 fn test_language_default() {
96 let lang = Language::default();
97 assert_eq!(lang.name, "Unknown");
98 assert!(lang.extensions.is_empty());
99 assert!(lang.line_comments.is_empty());
100 }
101
102 #[test]
103 fn test_language_deserialize() {
104 let toml = r#"
105 name = "Rust"
106 extensions = [".rs"]
107 line_comments = ["//"]
108 block_comments = [["/*", "*/"]]
109 function_pattern = "fn\\s+\\w+"
110 complexity_keywords = ["if", "for", "while"]
111 nested_comments = true
112 "#;
113
114 let lang: Language = toml::from_str(toml).unwrap();
115 assert_eq!(lang.name, "Rust");
116 assert_eq!(lang.extensions, vec![".rs"]);
117 assert_eq!(lang.line_comments, vec!["//"]);
118 assert_eq!(
119 lang.block_comments,
120 vec![("/*".to_string(), "*/".to_string())]
121 );
122 assert!(lang.nested_comments);
123 }
124}