pub mod json;
pub mod markdown;
pub mod source_comments;
pub mod yaml;
use std::path::Path;
use anyhow::Result;
use crate::file_type::FileType;
#[derive(Debug, Clone)]
pub struct ParsedDocument {
pub path: std::path::PathBuf,
pub file_type: FileType,
pub raw: String,
pub content: DocumentContent,
}
#[derive(Debug, Clone)]
pub enum DocumentContent {
Markdown(markdown::MarkdownDoc),
Yaml(serde_yaml::Value),
Json(serde_json::Value),
ParseError(String),
Text,
Empty,
}
pub fn parse(path: &Path, file_type: FileType) -> Result<ParsedDocument> {
let raw = std::fs::read_to_string(path)?;
let content = dispatch(&raw, file_type, path);
Ok(ParsedDocument {
path: path.to_path_buf(),
file_type,
raw,
content,
})
}
fn dispatch(raw: &str, file_type: FileType, path: &Path) -> DocumentContent {
if raw.is_empty() {
return DocumentContent::Empty;
}
let ext = path
.extension()
.and_then(|s| s.to_str())
.map(|s| s.to_ascii_lowercase());
let ext_str = ext.as_deref();
match file_type {
FileType::ClaudeMd
| FileType::AgentsMd
| FileType::CopilotCustomization
| FileType::CopilotInstructions
| FileType::JunieGuidelines
| FileType::AiderConventions
| FileType::GitHubSkill
| FileType::CustomProjectRules
| FileType::GenericMarkdown => DocumentContent::Markdown(markdown::parse(raw)),
FileType::CursorRules
| FileType::WindsurfRules
| FileType::ClineRules
| FileType::ContinueRules => match ext_str {
Some("md") | Some("markdown") | Some("mdc") => {
DocumentContent::Markdown(markdown::parse(raw))
}
Some("yaml") | Some("yml") => match yaml::parse(raw) {
Ok(v) => DocumentContent::Yaml(v),
Err(e) => DocumentContent::ParseError(e.to_string()),
},
Some("json") => match json::parse(raw) {
Ok(v) => DocumentContent::Json(v),
Err(e) => DocumentContent::ParseError(e.to_string()),
},
_ => DocumentContent::Markdown(markdown::parse(raw)),
},
FileType::GenericSystemPrompt => match ext_str {
Some("json") => match json::parse(raw) {
Ok(v) => DocumentContent::Json(v),
Err(e) => DocumentContent::ParseError(e.to_string()),
},
Some("yaml") | Some("yml") => match yaml::parse(raw) {
Ok(v) => DocumentContent::Yaml(v),
Err(e) => DocumentContent::ParseError(e.to_string()),
},
Some("md") | Some("markdown") => DocumentContent::Markdown(markdown::parse(raw)),
_ => DocumentContent::Markdown(markdown::parse(raw)),
},
FileType::GenericYaml => match yaml::parse(raw) {
Ok(v) => DocumentContent::Yaml(v),
Err(e) => DocumentContent::ParseError(e.to_string()),
},
FileType::McpConfig => match json::parse(raw) {
Ok(v) => DocumentContent::Json(v),
Err(e) => DocumentContent::ParseError(e.to_string()),
},
FileType::SourceCode(lang) => {
DocumentContent::Markdown(source_comments::synthesize(raw, lang))
}
FileType::Unknown => DocumentContent::Text,
}
}