pub(crate) mod go;
pub(crate) mod js;
pub(crate) mod json;
pub(crate) mod markdown;
pub(crate) mod python;
pub(crate) mod rust;
pub(crate) mod sql;
pub(crate) mod toml;
pub(crate) mod yaml;
use crate::{DefKind, Language};
pub(crate) fn caps<'t>(re: ®ex::Regex, line: &'t str) -> Option<regex::Captures<'t>> {
if re.is_match(line) {
re.captures(line)
} else {
None
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct Def {
pub kind: DefKind,
pub name: String,
pub scope: Option<String>,
pub line: usize,
pub start: usize,
pub end: usize,
}
pub(crate) fn extract(lang: Language, text: &str) -> Vec<Def> {
let lines: Vec<&str> = text.lines().collect();
let mut out = Vec::new();
match lang {
Language::Rust => rust::extract(&lines, &mut out),
Language::Python => python::extract(&lines, &mut out),
Language::JavaScript => js::extract(&lines, false, &mut out),
Language::TypeScript => js::extract(&lines, true, &mut out),
Language::Go => go::extract(&lines, &mut out),
Language::Sql => sql::extract(&lines, true, &mut out),
Language::Toml => toml::extract(&lines, &mut out),
Language::Yaml => yaml::extract(&lines, &mut out),
Language::Json => json::extract(&lines, &mut out),
Language::Markdown => markdown::extract(&lines, &mut out),
}
if !matches!(lang, Language::Sql | Language::Markdown | Language::Json) {
sql::extract(&lines, false, &mut out);
}
out.sort_by_key(|d| (d.line, d.start));
out.dedup_by(|a, b| a.line == b.line && a.name == b.name && a.kind == b.kind);
out
}
#[cfg(test)]
pub(crate) fn defs(
lang: Language,
text: &str,
) -> Vec<(DefKind, String, Option<String>, usize, usize, usize)> {
extract(lang, text)
.into_iter()
.map(|d| (d.kind, d.name, d.scope, d.start + 1, d.line + 1, d.end + 1))
.collect()
}