cel_cxx/function/
overload.rs

1//! Function overload management and resolution.
2//!
3//! This module provides types and utilities for managing function overloads,
4//! allowing multiple function implementations with different signatures to
5//! be registered under the same name.
6//!
7//! # Key Types
8//!
9//! - [`FunctionOverloads`]: Container for multiple overloads of a function
10//! - [`FunctionKindOverload`]: Overloads grouped by argument kinds  
11//! - [`FunctionDeclOrImpl`]: Union type for declarations and implementations
12//!
13//! # Overload Resolution
14//!
15//! The system supports sophisticated overload resolution based on:
16//! - **Argument count**: Number of parameters
17//! - **Argument types**: CEL types of each parameter
18//! - **Member vs global**: Whether the function is called as a method
19//!
20//! This enables natural function calls like:
21//! ```text
22//! // Different overloads of "format"
23//! format("Hello")              // format(string) -> string
24//! format("Hello %s", "World")  // format(string, string) -> string  
25//! format(42)                   // format(int) -> string
26//! ```
27
28use super::*;
29use crate::Kind;
30
31/// Collection of function overloads grouped by argument kinds.
32///
33/// `FunctionOverloads<T>` manages multiple function overloads that share the same name
34/// but have different argument signatures. This allows CEL to support function overloading
35/// based on argument types, similar to many programming languages.
36///
37/// # Type Parameters
38///
39/// - `T`: The type of function stored (implementation, declaration, or either)
40///
41/// # Examples
42///
43/// ```rust,no_run
44/// use cel_cxx::function::{FunctionOverloads, FunctionDeclOrImpl};
45///
46/// let mut overloads = FunctionOverloads::<FunctionDeclOrImpl>::new();
47/// // Add different overloads for the same function name
48/// ```
49#[derive(Debug, Default, Clone)]
50pub struct FunctionOverloads<T>(Vec<FunctionKindOverload<T>>);
51
52impl<T: FunctionTypeOverload> FunctionOverloads<T> {
53    /// Creates a new empty function overload collection.
54    pub fn new() -> Self {
55        Self(Vec::new())
56    }
57
58    /// Finds a function overload by member type and argument kinds.
59    ///
60    /// # Parameters
61    ///
62    /// - `member`: Whether to find member functions (true) or global functions (false)
63    /// - `kinds`: Argument kinds to match
64    ///
65    /// # Returns
66    ///
67    /// Returns `Some(&FunctionKindOverload)` if found, `None` otherwise
68    pub fn find(&self, member: bool, kinds: &[Kind]) -> Option<&FunctionKindOverload<T>> {
69        self.0
70            .iter()
71            .find(|overload| overload.member() == member && overload.argument_kinds() == kinds)
72    }
73
74    /// Finds a mutable reference to a function overload by member flag and argument kinds.
75    ///
76    /// # Parameters
77    ///
78    /// - `member`: Whether to search for member functions
79    /// - `kinds`: Argument kinds to match
80    ///
81    /// # Returns
82    ///
83    /// Mutable reference to the matching overload, or `None` if not found
84    pub fn find_mut(&mut self, member: bool, kinds: &[Kind]) -> Option<&mut FunctionKindOverload<T>>
85    where
86        T: Send + Sync,
87    {
88        self.0
89            .iter_mut()
90            .find(|overload| overload.member() == member && overload.argument_kinds() == kinds)
91    }
92
93    /// Returns an iterator over all function overloads.
94    ///
95    /// # Examples
96    ///
97    /// ```rust,no_run
98    /// use cel_cxx::function::{FunctionOverloads, FunctionDeclOrImpl};
99    ///
100    /// let overloads = FunctionOverloads::<FunctionDeclOrImpl<'_>>::new();
101    /// for overload in overloads.entries() {
102    ///     // Process each overload
103    /// }
104    /// ```
105    pub fn entries(&self) -> impl Iterator<Item = &FunctionKindOverload<T>> {
106        self.0.iter()
107    }
108
109    /// Returns a mutable iterator over all function overloads.
110    pub fn entries_mut(&mut self) -> impl Iterator<Item = &mut FunctionKindOverload<T>> {
111        self.0.iter_mut()
112    }
113
114    /// Clears all function overloads.
115    pub fn clear(&mut self) {
116        self.0.clear()
117    }
118
119    /// Removes a function overload by member flag and argument kinds.
120    ///
121    /// # Parameters
122    ///
123    /// - `member`: Whether to remove member functions
124    /// - `args`: Argument kinds to match for removal
125    ///
126    /// # Returns
127    ///
128    /// `Ok(())` if removal was successful, `Err(Error)` if not found
129    pub fn remove<I, K>(&mut self, member: bool, args: I) -> Result<(), Error>
130    where
131        I: IntoIterator<Item = K>,
132        K: Into<Kind>,
133    {
134        let kinds = args.into_iter().map(|k| k.into()).collect::<Vec<_>>();
135        if let Some(index) = self
136            .0
137            .iter()
138            .position(|overload| overload.member() == member && overload.argument_kinds() == &kinds)
139        {
140            self.0.remove(index);
141        } else {
142            return Err(Error::not_found(format!(
143                "Overload [{}] ({}) not found",
144                if member { "member" } else { "global" },
145                kinds
146                    .iter()
147                    .map(|k| k.to_string())
148                    .collect::<Vec<_>>()
149                    .join(", "),
150            )));
151        }
152        Ok(())
153    }
154}
155
156impl<'f> FunctionOverloads<FunctionDeclOrImpl<'f>> {
157    /// Adds a function implementation to the overloads.
158    ///
159    /// This method adds a concrete function implementation to the appropriate overload
160    /// group based on its signature. If no matching overload exists, a new one is created.
161    ///
162    /// # Arguments
163    ///
164    /// * `member` - Whether this is a member function
165    /// * `f` - The function implementation to add
166    ///
167    /// # Returns
168    ///
169    /// `Ok(&mut Self)` for method chaining, or `Err(Error)` if addition fails
170    ///
171    /// # Errors
172    ///
173    /// Returns error if the function signature conflicts with existing registrations.
174    pub fn add_impl(&mut self, member: bool, f: Function<'f>) -> Result<&mut Self, Error> {
175        if member && f.arguments_len() == 0 {
176            return Err(Error::invalid_argument("Member functions cannot have zero arguments"));
177        }
178        let kinds = f
179            .arguments()
180            .into_iter()
181            .map(|t| t.kind())
182            .collect::<Vec<_>>();
183        if let Some(overload) = self.find_mut(member, &kinds) {
184            overload.add_impl(f)?;
185        } else {
186            let mut overload = FunctionKindOverload::new(member, kinds);
187            overload.add_impl(f)?;
188            self.0.push(overload);
189        }
190        Ok(self)
191    }
192
193    /// Adds a function declaration to the overloads.
194    ///
195    /// This method adds a function type signature (declaration) to the appropriate
196    /// overload group. Declarations provide type information for compile-time checking
197    /// without requiring an implementation.
198    ///
199    /// # Arguments
200    ///
201    /// * `member` - Whether this is a member function declaration
202    /// * `f` - The function type signature to add
203    ///
204    /// # Returns
205    ///
206    /// `Ok(&mut Self)` for method chaining, or `Err(Error)` if addition fails
207    ///
208    /// # Errors
209    ///
210    /// Returns error if the function signature conflicts with existing registrations.
211    pub fn add_decl(&mut self, member: bool, f: FunctionType) -> Result<&mut Self, Error> {
212        if member && f.arguments().is_empty() {
213            return Err(Error::invalid_argument("Member functions cannot have zero arguments"));
214        }
215        let kinds = f.arguments().iter().map(|t| t.kind()).collect::<Vec<_>>();
216        if let Some(overload) = self.find_mut(member, &kinds) {
217            overload.add_decl(f)?;
218        } else {
219            let mut overload = FunctionKindOverload::new(member, kinds);
220            overload.add_decl(f)?;
221            self.0.push(overload);
222        }
223        Ok(self)
224    }
225}
226
227impl<'f> FunctionOverloads<Function<'f>> {
228    /// Adds a function to the overloads.
229    ///
230    /// This method adds a function to the appropriate overload group based on its
231    /// signature. This is used when working with pure function implementations
232    /// without separate declarations.
233    ///
234    /// # Arguments
235    ///
236    /// * `member` - Whether this is a member function
237    /// * `f` - The function to add
238    ///
239    /// # Returns
240    ///
241    /// `Ok(&mut Self)` for method chaining, or `Err(Error)` if addition fails
242    ///
243    /// # Errors
244    ///
245    /// Returns error if the function signature conflicts with existing registrations.
246    pub fn add(&mut self, member: bool, f: Function<'f>) -> Result<&mut Self, Error> {
247        let kinds = f
248            .arguments()
249            .into_iter()
250            .map(|t| t.kind())
251            .collect::<Vec<_>>();
252        if let Some(overload) = self.find_mut(member, &kinds) {
253            overload.add(f)?;
254        } else {
255            let mut overload = FunctionKindOverload::new(member, kinds);
256            overload.add(f)?;
257            self.0.push(overload);
258        }
259        Ok(self)
260    }
261}
262
263/// Trait for extracting argument types from function-like objects.
264///
265/// This trait provides a unified interface for getting argument type information
266/// from different kinds of function objects (implementations, declarations, etc.).
267/// It is used internally by the overload resolution system.
268///
269/// # Implementation Note
270///
271/// This trait is automatically implemented for function types that can provide
272/// argument type information. It should not be implemented manually.
273pub trait FunctionTypeOverload {
274    /// Returns the argument types for this function.
275    ///
276    /// # Returns
277    ///
278    /// A vector of [`ValueType`] representing the function's argument types.
279    fn arguments(&self) -> Vec<ValueType>;
280}
281
282impl FunctionTypeOverload for FunctionDeclOrImpl<'_> {
283    fn arguments(&self) -> Vec<ValueType> {
284        self.decl().arguments().to_vec()
285    }
286}
287
288impl FunctionTypeOverload for Function<'_> {
289    fn arguments(&self) -> Vec<ValueType> {
290        self.arguments()
291    }
292}
293
294/// Function overload for a specific argument kind signature.
295///
296/// `FunctionKindOverload` groups function implementations and declarations that have
297/// the same member flag and argument kinds. This allows for efficient lookup and
298/// type checking during function resolution.
299///
300/// # Type Parameters
301///
302/// - `T`: The type of function stored (implementation or declaration)
303///
304/// # Examples
305///
306/// ```rust,no_run
307/// use cel_cxx::{Kind, function::{FunctionKindOverload, Function}};
308///
309/// // Create overload for member function taking (string, int)
310/// let overload = FunctionKindOverload::<Function<'_>>::new(
311///     true,
312///     vec![Kind::String, Kind::Int]
313/// );
314/// ```
315#[derive(Debug, Clone)]
316pub struct FunctionKindOverload<T> {
317    member: bool,
318    argument_kinds: Vec<Kind>,
319    entries: Vec<T>,
320}
321
322impl<T: FunctionTypeOverload> FunctionKindOverload<T> {
323    /// Creates a new function kind overload.
324    ///
325    /// # Parameters
326    ///
327    /// - `member`: Whether this overload is for member functions
328    /// - `argument_kinds`: The argument kinds this overload handles
329    ///
330    /// # Returns
331    ///
332    /// New `FunctionKindOverload` instance
333    pub fn new(member: bool, argument_kinds: Vec<Kind>) -> Self {
334        Self {
335            member,
336            argument_kinds,
337            entries: Vec::new(),
338        }
339    }
340
341    /// Returns whether this overload is for member functions.
342    ///
343    /// # Returns
344    ///
345    /// `true` if this overload handles member functions, `false` for global functions
346    pub fn member(&self) -> bool {
347        self.member
348    }
349
350    /// Returns the argument kinds for this overload.
351    ///
352    /// # Returns
353    ///
354    /// Reference to the vector of argument kinds this overload handles
355    pub fn argument_kinds(&self) -> &Vec<Kind> {
356        &self.argument_kinds
357    }
358
359    /// Finds a function by exact argument types.
360    ///
361    /// # Parameters
362    ///
363    /// - `args`: Argument types to match
364    ///
365    /// # Returns
366    ///
367    /// Reference to the matching function, or `None` if not found
368    pub fn find(&self, args: &[ValueType]) -> Option<&T> {
369        self.entries.iter().find(|entry| entry.arguments() == args)
370    }
371
372    /// Returns an iterator over all functions in this overload.
373    ///
374    /// # Returns
375    ///
376    /// Iterator over references to all functions in this overload
377    pub fn entries(&self) -> impl Iterator<Item = &T> {
378        self.entries.iter()
379    }
380
381    /// Returns a mutable iterator over all functions in this overload.
382    ///
383    /// # Returns
384    ///
385    /// Iterator over mutable references to all functions in this overload
386    pub fn entries_mut(&mut self) -> impl Iterator<Item = &mut T> {
387        self.entries.iter_mut()
388    }
389
390    /// Clears all functions from this overload.
391    pub fn clear(&mut self) {
392        self.entries.clear();
393    }
394
395    /// Removes a function by exact argument types.
396    ///
397    /// # Parameters
398    ///
399    /// - `args`: Argument types to match for removal
400    ///
401    /// # Returns
402    ///
403    /// `Ok(())` if removal was successful, `Err(Error)` if not found
404    pub fn remove(&mut self, args: &[ValueType]) -> Result<(), Error> {
405        if let Some(index) = self
406            .entries
407            .iter()
408            .position(|entry| entry.arguments() == args)
409        {
410            self.entries.remove(index);
411        } else {
412            return Err(Error::not_found(format!(
413                "Overload [{}] ({}) not found",
414                if self.member { "member" } else { "global" },
415                args.iter()
416                    .map(|t| t.to_string())
417                    .collect::<Vec<_>>()
418                    .join(", "),
419            )));
420        }
421        Ok(())
422    }
423}
424
425impl<'f> FunctionKindOverload<FunctionDeclOrImpl<'f>> {
426    /// Adds a function implementation to this overload group.
427    ///
428    /// This method adds a concrete function implementation to the overload group.
429    /// The function signature must match the argument kinds of this overload group.
430    ///
431    /// # Arguments
432    ///
433    /// * `f` - The function implementation to add
434    ///
435    /// # Returns
436    ///
437    /// `Ok(&mut Self)` for method chaining, or `Err(Error)` if the function already exists
438    ///
439    /// # Errors
440    ///
441    /// Returns an error if a function with the same exact signature already exists.
442    pub fn add_impl(&mut self, f: Function<'f>) -> Result<&mut Self, Error> {
443        if let Some(_entry) = self.find(&f.arguments()) {
444            return Err(Error::invalid_argument("Function already exists"));
445        }
446        self.entries.push(FunctionDeclOrImpl::new_impl(f));
447        Ok(self)
448    }
449
450    /// Adds a function declaration to this overload group.
451    ///
452    /// This method adds a function type signature (declaration) to the overload group.
453    /// The function signature must match the argument kinds of this overload group.
454    ///
455    /// # Arguments
456    ///
457    /// * `r#type` - The function type signature to add
458    ///
459    /// # Returns
460    ///
461    /// `Ok(&mut Self)` for method chaining, or `Err(Error)` if the function already exists
462    ///
463    /// # Errors
464    ///
465    /// Returns an error if a function with the same exact signature already exists.
466    pub fn add_decl(&mut self, r#type: FunctionType) -> Result<&mut Self, Error> {
467        if let Some(_entry) = self.find(r#type.arguments()) {
468            return Err(Error::invalid_argument("Function already exists"));
469        }
470        self.entries.push(FunctionDeclOrImpl::new(r#type));
471        Ok(self)
472    }
473}
474
475impl<'f> FunctionKindOverload<Function<'f>> {
476    /// Adds a function (implementation or declaration) to this overload.
477    ///
478    /// This is a convenience method that automatically determines whether to add
479    /// an implementation or declaration based on the function type.
480    ///
481    /// # Type Parameters
482    ///
483    /// - `F`: Function type
484    /// - `M`: Function marker (sync/async)
485    /// - `E`: Error type
486    /// - `R`: Return type
487    /// - `A`: Argument tuple type
488    ///
489    /// # Parameters
490    ///
491    /// - `f`: Function to add
492    ///
493    /// # Returns
494    ///
495    /// Mutable reference to self for chaining, or error if addition failed
496    pub fn add(&mut self, f: Function<'f>) -> Result<&mut Self, Error> {
497        if let Some(_entry) = self.find(&f.arguments()) {
498            return Err(Error::invalid_argument("Function already exists"));
499        }
500        self.entries.push(f);
501        Ok(self)
502    }
503}
504
505/// Union type representing either a function declaration or implementation.
506///
507/// `FunctionDeclOrImpl` can hold either:
508/// - A function type signature (declaration) for compile-time type checking
509/// - A concrete function implementation for runtime execution
510/// - Both a declaration and implementation (preferred)
511///
512/// This allows the system to provide type information even when implementations
513/// are not available, enabling better compile-time checking and error reporting.
514///
515/// # Examples
516///
517/// ```rust,no_run
518/// use cel_cxx::function::{FunctionDeclOrImpl, IntoFunction};
519/// use cel_cxx::types::{ValueType, FunctionType};
520///
521/// // Create from declaration only
522/// let func_type = FunctionType::new(ValueType::Int, vec![ValueType::Int]);
523/// let decl_only = FunctionDeclOrImpl::new(func_type);
524///
525/// // Create from implementation (includes both decl and impl)
526/// let func = (|a: i32, b: i32| -> i32 { a + b }).into_function();
527/// let with_impl = FunctionDeclOrImpl::new_impl(func);
528/// ```
529#[derive(Debug, Clone)]
530pub struct FunctionDeclOrImpl<'f> {
531    r#type: FunctionType,
532    r#impl: Option<Function<'f>>,
533}
534
535impl<'f> FunctionDeclOrImpl<'f> {
536    /// Creates a new `FunctionDeclOrImpl` from a function implementation.
537    ///
538    /// This constructor creates both the declaration (extracted from the function's
539    /// type signature) and stores the implementation for runtime execution.
540    ///
541    /// # Arguments
542    ///
543    /// * `r#impl` - The function implementation
544    ///
545    /// # Returns
546    ///
547    /// New `FunctionDeclOrImpl` containing both declaration and implementation
548    pub fn new_impl(r#impl: Function<'f>) -> Self {
549        Self {
550            r#type: r#impl.function_type(),
551            r#impl: Some(r#impl),
552        }
553    }
554
555    /// Creates a new `FunctionDeclOrImpl` from a function type declaration.
556    ///
557    /// This constructor creates a declaration-only entry, useful for providing
558    /// type information without requiring an implementation.
559    ///
560    /// # Arguments
561    ///
562    /// * `r#type` - The function type signature
563    ///
564    /// # Returns
565    ///
566    /// New `FunctionDeclOrImpl` containing only the declaration
567    pub fn new(r#type: FunctionType) -> Self {
568        Self {
569            r#type,
570            r#impl: None,
571        }
572    }
573
574    /// Returns whether this entry has a concrete implementation.
575    ///
576    /// # Returns
577    ///
578    /// `true` if this entry contains a function implementation, `false` if declaration-only
579    pub fn is_impl(&self) -> bool {
580        self.r#impl.is_some()
581    }
582
583    /// Gets the function type declaration.
584    ///
585    /// # Returns
586    ///
587    /// Reference to the function type signature
588    pub fn decl(&self) -> &FunctionType {
589        &self.r#type
590    }
591
592    /// Gets the function implementation, if available.
593    ///
594    /// # Returns
595    ///
596    /// `Some(&Function)` if implementation is available, `None` for declaration-only entries
597    pub fn r#impl(&self) -> Option<&Function<'f>> {
598        self.r#impl.as_ref()
599    }
600}