mago_analyzer/plugin/provider/
function.rs1use mago_atom::starts_with_ignore_case;
4use mago_codex::ttype::union::TUnion;
5
6use crate::plugin::context::InvocationInfo;
7use crate::plugin::context::ProviderContext;
8use crate::plugin::provider::Provider;
9
10#[derive(Debug, Clone, PartialEq, Eq)]
11pub enum FunctionTarget {
12 Exact(&'static str),
13 ExactMultiple(&'static [&'static str]),
14 Prefix(&'static str),
15 Namespace(&'static str),
16}
17
18impl FunctionTarget {
19 #[inline]
20 #[must_use]
21 pub const fn exact(name: &'static str) -> Self {
22 Self::Exact(name)
23 }
24
25 #[inline]
26 #[must_use]
27 pub const fn exact_multiple(names: &'static [&'static str]) -> Self {
28 Self::ExactMultiple(names)
29 }
30
31 #[inline]
32 #[must_use]
33 pub const fn prefix(prefix: &'static str) -> Self {
34 Self::Prefix(prefix)
35 }
36
37 #[inline]
38 #[must_use]
39 pub const fn namespace(ns: &'static str) -> Self {
40 Self::Namespace(ns)
41 }
42
43 #[must_use]
44 pub fn matches(&self, name: &str) -> bool {
45 match self {
46 FunctionTarget::Exact(target) => name.eq_ignore_ascii_case(target),
47 FunctionTarget::ExactMultiple(targets) => targets.iter().any(|target| name.eq_ignore_ascii_case(target)),
48 FunctionTarget::Prefix(prefix) => starts_with_ignore_case(name, prefix),
49 FunctionTarget::Namespace(ns) => starts_with_ignore_case(name, ns),
50 }
51 }
52
53 #[must_use]
54 pub fn get_exact_names(&self) -> Option<Vec<&'static str>> {
55 match self {
56 FunctionTarget::Exact(name) => Some(vec![*name]),
57 FunctionTarget::ExactMultiple(names) => Some(names.to_vec()),
58 FunctionTarget::Prefix(_) | FunctionTarget::Namespace(_) => None,
59 }
60 }
61
62 #[must_use]
63 pub fn is_prefix(&self) -> bool {
64 matches!(self, FunctionTarget::Prefix(_))
65 }
66
67 #[must_use]
68 pub fn is_namespace(&self) -> bool {
69 matches!(self, FunctionTarget::Namespace(_))
70 }
71
72 #[must_use]
73 pub fn get_prefix(&self) -> Option<&'static str> {
74 match self {
75 FunctionTarget::Prefix(prefix) => Some(prefix),
76 _ => None,
77 }
78 }
79
80 #[must_use]
81 pub fn get_namespace(&self) -> Option<&'static str> {
82 match self {
83 FunctionTarget::Namespace(ns) => Some(ns),
84 _ => None,
85 }
86 }
87}
88
89pub trait FunctionReturnTypeProvider: Provider {
90 fn targets() -> FunctionTarget
91 where
92 Self: Sized;
93
94 fn get_return_type(
95 &self,
96 context: &ProviderContext<'_, '_, '_>,
97 invocation: &InvocationInfo<'_, '_, '_>,
98 ) -> Option<TUnion>;
99}