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}