use std::path::Path;
use crate::payload::ParsedFilePayload;
pub mod python;
pub mod rust;
pub mod typescript;
pub use python::PythonAstParser;
pub use rust::{
ExtractedUseItem, RustAstParser, crate_root_for, dependency_module_path_for,
extract_type_members, extract_use_items, module_path_for,
};
pub use typescript::TypeScriptAstParser;
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub enum ParseMode {
#[default]
Workspace,
DependencyPublicSurface {
crate_name: String,
},
}
impl ParseMode {
pub fn is_dependency_public_surface(&self) -> bool {
matches!(self, Self::DependencyPublicSurface { .. })
}
pub fn crate_name(&self) -> Option<&str> {
match self {
Self::Workspace => None,
Self::DependencyPublicSurface { crate_name } => Some(crate_name.as_str()),
}
}
}
pub fn parse_file(
relative_path: &Path,
content: &[u8],
content_hash: &str,
mode: ParseMode,
) -> anyhow::Result<ParsedFilePayload> {
let ext = relative_path
.extension()
.and_then(|e| e.to_str())
.unwrap_or("")
.to_ascii_lowercase();
match ext.as_str() {
"rs" => RustAstParser::parse(relative_path, content, content_hash, mode),
"py" => PythonAstParser::parse(relative_path, content, content_hash),
"ts" | "tsx" | "js" | "jsx" => {
TypeScriptAstParser::parse(relative_path, content, content_hash)
}
other => anyhow::bail!(
"Unsupported file extension '{other}' for {}",
relative_path.display()
),
}
}