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        let kinds = f
176            .arguments()
177            .into_iter()
178            .map(|t| t.kind())
179            .collect::<Vec<_>>();
180        if let Some(overload) = self.find_mut(member, &kinds) {
181            overload.add_impl(f)?;
182        } else {
183            let mut overload = FunctionKindOverload::new(member, kinds);
184            overload.add_impl(f)?;
185            self.0.push(overload);
186        }
187        Ok(self)
188    }
189
190    /// Adds a function declaration to the overloads.
191    ///
192    /// This method adds a function type signature (declaration) to the appropriate
193    /// overload group. Declarations provide type information for compile-time checking
194    /// without requiring an implementation.
195    ///
196    /// # Arguments
197    ///
198    /// * `member` - Whether this is a member function declaration
199    /// * `f` - The function type signature to add
200    ///
201    /// # Returns
202    ///
203    /// `Ok(&mut Self)` for method chaining, or `Err(Error)` if addition fails
204    ///
205    /// # Errors
206    ///
207    /// Returns error if the function signature conflicts with existing registrations.
208    pub fn add_decl(&mut self, member: bool, f: FunctionType) -> Result<&mut Self, Error> {
209        let kinds = f.arguments().iter().map(|t| t.kind()).collect::<Vec<_>>();
210        if let Some(overload) = self.find_mut(member, &kinds) {
211            overload.add_decl(f)?;
212        } else {
213            let mut overload = FunctionKindOverload::new(member, kinds);
214            overload.add_decl(f)?;
215            self.0.push(overload);
216        }
217        Ok(self)
218    }
219}
220
221impl<'f> FunctionOverloads<Function<'f>> {
222    /// Adds a function to the overloads.
223    ///
224    /// This method adds a function to the appropriate overload group based on its
225    /// signature. This is used when working with pure function implementations
226    /// without separate declarations.
227    ///
228    /// # Arguments
229    ///
230    /// * `member` - Whether this is a member function
231    /// * `f` - The function to add
232    ///
233    /// # Returns
234    ///
235    /// `Ok(&mut Self)` for method chaining, or `Err(Error)` if addition fails
236    ///
237    /// # Errors
238    ///
239    /// Returns error if the function signature conflicts with existing registrations.
240    pub fn add(&mut self, member: bool, f: Function<'f>) -> Result<&mut Self, Error> {
241        let kinds = f
242            .arguments()
243            .into_iter()
244            .map(|t| t.kind())
245            .collect::<Vec<_>>();
246        if let Some(overload) = self.find_mut(member, &kinds) {
247            overload.add(f)?;
248        } else {
249            let mut overload = FunctionKindOverload::new(member, kinds);
250            overload.add(f)?;
251            self.0.push(overload);
252        }
253        Ok(self)
254    }
255}
256
257/// Trait for extracting argument types from function-like objects.
258///
259/// This trait provides a unified interface for getting argument type information
260/// from different kinds of function objects (implementations, declarations, etc.).
261/// It is used internally by the overload resolution system.
262///
263/// # Implementation Note
264///
265/// This trait is automatically implemented for function types that can provide
266/// argument type information. It should not be implemented manually.
267pub trait FunctionTypeOverload {
268    /// Returns the argument types for this function.
269    ///
270    /// # Returns
271    ///
272    /// A vector of [`ValueType`] representing the function's argument types.
273    fn arguments(&self) -> Vec<ValueType>;
274}
275
276impl FunctionTypeOverload for FunctionDeclOrImpl<'_> {
277    fn arguments(&self) -> Vec<ValueType> {
278        self.decl().arguments().to_vec()
279    }
280}
281
282impl FunctionTypeOverload for Function<'_> {
283    fn arguments(&self) -> Vec<ValueType> {
284        self.arguments()
285    }
286}
287
288/// Function overload for a specific argument kind signature.
289///
290/// `FunctionKindOverload` groups function implementations and declarations that have
291/// the same member flag and argument kinds. This allows for efficient lookup and
292/// type checking during function resolution.
293///
294/// # Type Parameters
295///
296/// - `T`: The type of function stored (implementation or declaration)
297///
298/// # Examples
299///
300/// ```rust,no_run
301/// use cel_cxx::{Kind, function::{FunctionKindOverload, Function}};
302///
303/// // Create overload for member function taking (string, int)
304/// let overload = FunctionKindOverload::<Function<'_>>::new(
305///     true,
306///     vec![Kind::String, Kind::Int]
307/// );
308/// ```
309#[derive(Debug, Clone)]
310pub struct FunctionKindOverload<T> {
311    member: bool,
312    argument_kinds: Vec<Kind>,
313    entries: Vec<T>,
314}
315
316impl<T: FunctionTypeOverload> FunctionKindOverload<T> {
317    /// Creates a new function kind overload.
318    ///
319    /// # Parameters
320    ///
321    /// - `member`: Whether this overload is for member functions
322    /// - `argument_kinds`: The argument kinds this overload handles
323    ///
324    /// # Returns
325    ///
326    /// New `FunctionKindOverload` instance
327    pub fn new(member: bool, argument_kinds: Vec<Kind>) -> Self {
328        Self {
329            member,
330            argument_kinds,
331            entries: Vec::new(),
332        }
333    }
334
335    /// Returns whether this overload is for member functions.
336    ///
337    /// # Returns
338    ///
339    /// `true` if this overload handles member functions, `false` for global functions
340    pub fn member(&self) -> bool {
341        self.member
342    }
343
344    /// Returns the argument kinds for this overload.
345    ///
346    /// # Returns
347    ///
348    /// Reference to the vector of argument kinds this overload handles
349    pub fn argument_kinds(&self) -> &Vec<Kind> {
350        &self.argument_kinds
351    }
352
353    /// Finds a function by exact argument types.
354    ///
355    /// # Parameters
356    ///
357    /// - `args`: Argument types to match
358    ///
359    /// # Returns
360    ///
361    /// Reference to the matching function, or `None` if not found
362    pub fn find(&self, args: &[ValueType]) -> Option<&T> {
363        self.entries.iter().find(|entry| entry.arguments() == args)
364    }
365
366    /// Returns an iterator over all functions in this overload.
367    ///
368    /// # Returns
369    ///
370    /// Iterator over references to all functions in this overload
371    pub fn entries(&self) -> impl Iterator<Item = &T> {
372        self.entries.iter()
373    }
374
375    /// Returns a mutable iterator over all functions in this overload.
376    ///
377    /// # Returns
378    ///
379    /// Iterator over mutable references to all functions in this overload
380    pub fn entries_mut(&mut self) -> impl Iterator<Item = &mut T> {
381        self.entries.iter_mut()
382    }
383
384    /// Clears all functions from this overload.
385    pub fn clear(&mut self) {
386        self.entries.clear();
387    }
388
389    /// Removes a function by exact argument types.
390    ///
391    /// # Parameters
392    ///
393    /// - `args`: Argument types to match for removal
394    ///
395    /// # Returns
396    ///
397    /// `Ok(())` if removal was successful, `Err(Error)` if not found
398    pub fn remove(&mut self, args: &[ValueType]) -> Result<(), Error> {
399        if let Some(index) = self
400            .entries
401            .iter()
402            .position(|entry| entry.arguments() == args)
403        {
404            self.entries.remove(index);
405        } else {
406            return Err(Error::not_found(format!(
407                "Overload [{}] ({}) not found",
408                if self.member { "member" } else { "global" },
409                args.iter()
410                    .map(|t| t.to_string())
411                    .collect::<Vec<_>>()
412                    .join(", "),
413            )));
414        }
415        Ok(())
416    }
417}
418
419impl<'f> FunctionKindOverload<FunctionDeclOrImpl<'f>> {
420    /// Adds a function implementation to this overload group.
421    ///
422    /// This method adds a concrete function implementation to the overload group.
423    /// The function signature must match the argument kinds of this overload group.
424    ///
425    /// # Arguments
426    ///
427    /// * `f` - The function implementation to add
428    ///
429    /// # Returns
430    ///
431    /// `Ok(&mut Self)` for method chaining, or `Err(Error)` if the function already exists
432    ///
433    /// # Errors
434    ///
435    /// Returns an error if a function with the same exact signature already exists.
436    pub fn add_impl(&mut self, f: Function<'f>) -> Result<&mut Self, Error> {
437        if let Some(_entry) = self.find(&f.arguments()) {
438            return Err(Error::invalid_argument("Function already exists"));
439        }
440        self.entries.push(FunctionDeclOrImpl::new_impl(f));
441        Ok(self)
442    }
443
444    /// Adds a function declaration to this overload group.
445    ///
446    /// This method adds a function type signature (declaration) to the overload group.
447    /// The function signature must match the argument kinds of this overload group.
448    ///
449    /// # Arguments
450    ///
451    /// * `r#type` - The function type signature to add
452    ///
453    /// # Returns
454    ///
455    /// `Ok(&mut Self)` for method chaining, or `Err(Error)` if the function already exists
456    ///
457    /// # Errors
458    ///
459    /// Returns an error if a function with the same exact signature already exists.
460    pub fn add_decl(&mut self, r#type: FunctionType) -> Result<&mut Self, Error> {
461        if let Some(_entry) = self.find(r#type.arguments()) {
462            return Err(Error::invalid_argument("Function already exists"));
463        }
464        self.entries.push(FunctionDeclOrImpl::new(r#type));
465        Ok(self)
466    }
467}
468
469impl<'f> FunctionKindOverload<Function<'f>> {
470    /// Adds a function (implementation or declaration) to this overload.
471    ///
472    /// This is a convenience method that automatically determines whether to add
473    /// an implementation or declaration based on the function type.
474    ///
475    /// # Type Parameters
476    ///
477    /// - `F`: Function type
478    /// - `M`: Function marker (sync/async)
479    /// - `E`: Error type
480    /// - `R`: Return type
481    /// - `A`: Argument tuple type
482    ///
483    /// # Parameters
484    ///
485    /// - `f`: Function to add
486    ///
487    /// # Returns
488    ///
489    /// Mutable reference to self for chaining, or error if addition failed
490    pub fn add(&mut self, f: Function<'f>) -> Result<&mut Self, Error> {
491        if let Some(_entry) = self.find(&f.arguments()) {
492            return Err(Error::invalid_argument("Function already exists"));
493        }
494        self.entries.push(f);
495        Ok(self)
496    }
497}
498
499/// Union type representing either a function declaration or implementation.
500///
501/// `FunctionDeclOrImpl` can hold either:
502/// - A function type signature (declaration) for compile-time type checking
503/// - A concrete function implementation for runtime execution
504/// - Both a declaration and implementation (preferred)
505///
506/// This allows the system to provide type information even when implementations
507/// are not available, enabling better compile-time checking and error reporting.
508///
509/// # Examples
510///
511/// ```rust,no_run
512/// use cel_cxx::function::{FunctionDeclOrImpl, IntoFunction};
513/// use cel_cxx::types::{ValueType, FunctionType};
514///
515/// // Create from declaration only
516/// let func_type = FunctionType::new(ValueType::Int, vec![ValueType::Int]);
517/// let decl_only = FunctionDeclOrImpl::new(func_type);
518///
519/// // Create from implementation (includes both decl and impl)
520/// let func = (|a: i32, b: i32| -> i32 { a + b }).into_function();
521/// let with_impl = FunctionDeclOrImpl::new_impl(func);
522/// ```
523#[derive(Debug, Clone)]
524pub struct FunctionDeclOrImpl<'f> {
525    r#type: FunctionType,
526    r#impl: Option<Function<'f>>,
527}
528
529impl<'f> FunctionDeclOrImpl<'f> {
530    /// Creates a new `FunctionDeclOrImpl` from a function implementation.
531    ///
532    /// This constructor creates both the declaration (extracted from the function's
533    /// type signature) and stores the implementation for runtime execution.
534    ///
535    /// # Arguments
536    ///
537    /// * `r#impl` - The function implementation
538    ///
539    /// # Returns
540    ///
541    /// New `FunctionDeclOrImpl` containing both declaration and implementation
542    pub fn new_impl(r#impl: Function<'f>) -> Self {
543        Self {
544            r#type: r#impl.function_type(),
545            r#impl: Some(r#impl),
546        }
547    }
548
549    /// Creates a new `FunctionDeclOrImpl` from a function type declaration.
550    ///
551    /// This constructor creates a declaration-only entry, useful for providing
552    /// type information without requiring an implementation.
553    ///
554    /// # Arguments
555    ///
556    /// * `r#type` - The function type signature
557    ///
558    /// # Returns
559    ///
560    /// New `FunctionDeclOrImpl` containing only the declaration
561    pub fn new(r#type: FunctionType) -> Self {
562        Self {
563            r#type,
564            r#impl: None,
565        }
566    }
567
568    /// Returns whether this entry has a concrete implementation.
569    ///
570    /// # Returns
571    ///
572    /// `true` if this entry contains a function implementation, `false` if declaration-only
573    pub fn is_impl(&self) -> bool {
574        self.r#impl.is_some()
575    }
576
577    /// Gets the function type declaration.
578    ///
579    /// # Returns
580    ///
581    /// Reference to the function type signature
582    pub fn decl(&self) -> &FunctionType {
583        &self.r#type
584    }
585
586    /// Gets the function implementation, if available.
587    ///
588    /// # Returns
589    ///
590    /// `Some(&Function)` if implementation is available, `None` for declaration-only entries
591    pub fn r#impl(&self) -> Option<&Function<'f>> {
592        self.r#impl.as_ref()
593    }
594}