use std::sync::LazyLock;
use regex::Regex;
pub const NODE_KINDS: &[&str] = &[];
static TS_JS_RE: LazyLock<Regex> = LazyLock::new(|| {
Regex::new(r"^(z|yup|v|s)\.\w|\.safeParse\(").expect("schema_validation TS/JS regex is valid")
});
static PYTHON_RE: LazyLock<Regex> = LazyLock::new(|| {
Regex::new(r"\bField\(|\bconstr\(|\bconint\(").expect("schema_validation Python regex is valid")
});
pub fn matches_callee(text: &str, language: &str) -> bool {
match language {
"typescript" | "javascript" => TS_JS_RE.is_match(text),
"python" => PYTHON_RE.is_match(text),
_ => false,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn zod_namespace_matches_typescript() {
for callee in [
"z.object({})",
"z.string()",
"z.enum(['a','b'])",
"z.union([])",
] {
assert!(
matches_callee(callee, "typescript"),
"{callee:?} should match for typescript"
);
}
}
#[test]
fn yup_namespace_matches() {
assert!(matches_callee("yup.object().shape({})", "typescript"));
assert!(matches_callee("yup.string().required()", "javascript"));
}
#[test]
fn valibot_namespace_matches() {
assert!(matches_callee("v.object({})", "typescript"));
assert!(matches_callee(
"v.pipe(v.string(), v.minLength(1))",
"javascript"
));
}
#[test]
fn superstruct_namespace_matches() {
assert!(matches_callee("s.object({})", "typescript"));
}
#[test]
fn safe_parse_matches() {
assert!(matches_callee("UserSchema.safeParse(input)", "typescript"));
assert!(matches_callee("schema.safeParse(data)", "javascript"));
}
#[test]
fn pydantic_field_matches_python() {
assert!(matches_callee("Field(default=0)", "python"));
assert!(matches_callee("Field(...)", "python"));
assert!(matches_callee("constr(min_length=1)", "python"));
assert!(matches_callee("conint(gt=0)", "python"));
}
#[test]
fn bare_method_call_does_not_match() {
assert!(!matches_callee(".string()", "typescript"));
assert!(!matches_callee(".object()", "typescript"));
assert!(!matches_callee("parse(x)", "typescript"));
assert!(!matches_callee("Math.max(a, b)", "typescript"));
}
#[test]
fn generic_python_calls_do_not_match() {
assert!(!matches_callee("len(x)", "python"));
assert!(!matches_callee("open(path)", "python"));
}
#[test]
fn other_languages_return_false() {
for lang in ["rust", "go", "java"] {
assert!(
!matches_callee("z.object({})", lang),
"z.object should not match for {lang}"
);
}
}
#[test]
fn node_kinds_is_empty() {
#[allow(clippy::const_is_empty)]
let empty = NODE_KINDS.is_empty();
assert!(empty);
}
}