use mollify_parse::Definition;
const ENTRY_DECORATORS: &[&str] = &[
"route",
"get",
"post",
"put",
"patch",
"delete",
"head",
"options",
"websocket",
"websocket_route",
"middleware",
"exception_handler",
"on_event",
"before_request",
"after_request",
"errorhandler",
"task",
"shared_task",
"periodic_task",
"actor",
"scheduled_job",
"on_message",
"subscribe",
"fixture",
"hookimpl",
"receiver",
"register",
"display",
"action",
"simple_tag",
"filter",
"inclusion_tag",
"admin",
"command",
"group",
"callback",
"validator",
"field_validator",
"root_validator",
"model_validator",
"field_serializer",
"model_serializer",
"computed_field",
"hook",
"plugin",
"rule",
"event",
"listener",
"handler",
"provides",
"implementer",
"setup",
"teardown",
];
pub fn is_framework_entry_decorator(dec: &str) -> bool {
let seg = dec.rsplit('.').next().unwrap_or(dec);
ENTRY_DECORATORS.contains(&seg)
}
pub fn is_framework_entry(def: &Definition) -> bool {
def.decorators
.iter()
.any(|d| is_framework_entry_decorator(d))
}
#[cfg(test)]
mod tests {
use super::*;
use mollify_parse::DefKind;
fn def(decorators: &[&str]) -> Definition {
Definition {
name: "x".into(),
kind: DefKind::Function,
line: 1,
end_line: 2,
private_by_convention: false,
decorators: decorators.iter().map(|s| s.to_string()).collect(),
}
}
#[test]
fn recognizes_framework_decorators() {
assert!(is_framework_entry(&def(&["app.route"])));
assert!(is_framework_entry(&def(&["router.get"])));
assert!(is_framework_entry(&def(&["pytest.fixture"])));
assert!(is_framework_entry(&def(&["shared_task"])));
assert!(is_framework_entry(&def(&["receiver"])));
assert!(is_framework_entry(&def(&["cli.command"])));
assert!(is_framework_entry(&def(&["field_validator"])));
}
#[test]
fn ignores_plain_decorators() {
assert!(!is_framework_entry(&def(&["staticmethod"])));
assert!(!is_framework_entry(&def(&["functools.lru_cache"])));
assert!(!is_framework_entry(&def(&[])));
}
}