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}