1use super::traits::{ContentParser, ContentType, ParsedContent};
4use crate::error::Result;
5
6pub struct TomlParser;
8
9impl TomlParser {
10 pub fn new() -> Self {
12 Self
13 }
14
15 pub fn parse_value(content: &str) -> Option<serde_json::Value> {
17 toml::from_str::<toml::Value>(content)
18 .ok()
19 .and_then(|v| serde_json::to_value(v).ok())
20 }
21
22 pub fn parse_toml_value(content: &str) -> Option<toml::Value> {
24 toml::from_str(content).ok()
25 }
26}
27
28impl Default for TomlParser {
29 fn default() -> Self {
30 Self::new()
31 }
32}
33
34impl ContentParser for TomlParser {
35 fn parse(&self, content: &str, path: &str) -> Result<ParsedContent> {
36 let mut parsed =
37 ParsedContent::new(ContentType::Toml, content.to_string(), path.to_string());
38
39 if let Some(value) = Self::parse_value(content) {
41 parsed = parsed.with_structured_data(value);
42 }
43
44 Ok(parsed)
45 }
46
47 fn supported_extensions(&self) -> &[&str] {
48 &[".toml"]
49 }
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55
56 #[test]
57 fn test_parse_valid_toml() {
58 let parser = TomlParser::new();
59 let content = r#"
60[package]
61name = "test"
62version = "1.0.0"
63"#;
64 let result = parser.parse(content, "Cargo.toml").unwrap();
65
66 assert_eq!(result.content_type, ContentType::Toml);
67 assert!(result.structured_data.is_some());
68 let data = result.structured_data.unwrap();
69 assert_eq!(data["package"]["name"].as_str(), Some("test"));
70 }
71
72 #[test]
73 fn test_parse_invalid_toml() {
74 let parser = TomlParser::new();
75 let content = "invalid = toml [";
76 let result = parser.parse(content, "config.toml").unwrap();
77
78 assert_eq!(result.content_type, ContentType::Toml);
79 assert!(result.structured_data.is_none());
80 }
81
82 #[test]
83 fn test_supported_extensions() {
84 let parser = TomlParser::new();
85 assert!(parser.can_parse("Cargo.toml"));
86 assert!(parser.can_parse("pyproject.toml"));
87 assert!(!parser.can_parse("config.json"));
88 }
89
90 #[test]
91 fn test_parse_pyproject_toml() {
92 let parser = TomlParser::new();
93 let content = r#"
94[project]
95name = "myproject"
96version = "0.1.0"
97
98[project.dependencies]
99requests = "^2.28"
100"#;
101 let result = parser.parse(content, "pyproject.toml").unwrap();
102
103 assert!(result.structured_data.is_some());
104 let data = result.structured_data.unwrap();
105 assert_eq!(data["project"]["name"].as_str(), Some("myproject"));
106 }
107}