ailint_core/parser/
mod.rs1pub mod json;
4pub mod markdown;
5pub mod source_comments;
6pub mod yaml;
7
8use std::path::Path;
9
10use anyhow::Result;
11
12use crate::file_type::FileType;
13
14#[derive(Debug, Clone)]
16pub struct ParsedDocument {
17 pub path: std::path::PathBuf,
19 pub file_type: FileType,
21 pub raw: String,
23 pub content: DocumentContent,
25}
26
27#[derive(Debug, Clone)]
29pub enum DocumentContent {
30 Markdown(markdown::MarkdownDoc),
32 Yaml(serde_yaml::Value),
34 Json(serde_json::Value),
36 ParseError(String),
40 Text,
42 Empty,
44}
45
46pub fn parse(path: &Path, file_type: FileType) -> Result<ParsedDocument> {
48 let raw = std::fs::read_to_string(path)?;
49 let content = dispatch(&raw, file_type, path);
50 Ok(ParsedDocument {
51 path: path.to_path_buf(),
52 file_type,
53 raw,
54 content,
55 })
56}
57
58fn dispatch(raw: &str, file_type: FileType, path: &Path) -> DocumentContent {
59 if raw.is_empty() {
60 return DocumentContent::Empty;
61 }
62 let ext = path
63 .extension()
64 .and_then(|s| s.to_str())
65 .map(|s| s.to_ascii_lowercase());
66 let ext_str = ext.as_deref();
67
68 match file_type {
69 FileType::ClaudeMd
70 | FileType::AgentsMd
71 | FileType::CopilotCustomization
72 | FileType::CopilotInstructions
73 | FileType::JunieGuidelines
74 | FileType::AiderConventions
75 | FileType::GitHubSkill
76 | FileType::CustomProjectRules
77 | FileType::GenericMarkdown => DocumentContent::Markdown(markdown::parse(raw)),
78
79 FileType::CursorRules
80 | FileType::WindsurfRules
81 | FileType::ClineRules
82 | FileType::ContinueRules => match ext_str {
83 Some("md") | Some("markdown") | Some("mdc") => {
84 DocumentContent::Markdown(markdown::parse(raw))
85 }
86 Some("yaml") | Some("yml") => match yaml::parse(raw) {
87 Ok(v) => DocumentContent::Yaml(v),
88 Err(e) => DocumentContent::ParseError(e.to_string()),
89 },
90 Some("json") => match json::parse(raw) {
91 Ok(v) => DocumentContent::Json(v),
92 Err(e) => DocumentContent::ParseError(e.to_string()),
93 },
94 _ => DocumentContent::Markdown(markdown::parse(raw)),
95 },
96
97 FileType::GenericSystemPrompt => match ext_str {
98 Some("json") => match json::parse(raw) {
99 Ok(v) => DocumentContent::Json(v),
100 Err(e) => DocumentContent::ParseError(e.to_string()),
101 },
102 Some("yaml") | Some("yml") => match yaml::parse(raw) {
103 Ok(v) => DocumentContent::Yaml(v),
104 Err(e) => DocumentContent::ParseError(e.to_string()),
105 },
106 Some("md") | Some("markdown") => DocumentContent::Markdown(markdown::parse(raw)),
107 _ => DocumentContent::Markdown(markdown::parse(raw)),
108 },
109
110 FileType::GenericYaml => match yaml::parse(raw) {
111 Ok(v) => DocumentContent::Yaml(v),
112 Err(e) => DocumentContent::ParseError(e.to_string()),
113 },
114
115 FileType::McpConfig => match json::parse(raw) {
116 Ok(v) => DocumentContent::Json(v),
117 Err(e) => DocumentContent::ParseError(e.to_string()),
118 },
119
120 FileType::SourceCode(lang) => {
121 DocumentContent::Markdown(source_comments::synthesize(raw, lang))
122 }
123
124 FileType::Unknown => DocumentContent::Text,
125 }
126}