1use anyhow::{anyhow, Result};
2use std::collections::HashMap;
3use std::fmt;
4use std::sync::Arc;
5
6use crate::data::datatable::DataValue;
7
8pub mod astronomy;
9pub mod base_conversion;
10pub mod bigint;
11pub mod case_convert;
12pub mod chemistry;
13pub mod comparison;
14pub mod constants;
15pub mod convert;
16pub mod date_time;
17pub mod financial;
18pub mod format;
19pub mod format_number;
20pub mod geometry;
21pub mod group_num;
22pub mod hash;
23pub mod integer_limits;
24pub mod math;
25pub mod mathematics;
26pub mod number_words;
27pub mod particle_charges;
28pub mod physics;
29pub mod random;
30pub mod roman;
31pub mod solar_system;
32pub mod statistics;
33pub mod string_fun;
34pub mod string_methods;
35pub mod string_utils;
36pub mod text_processing;
37pub mod trigonometry;
38pub mod type_checking;
39
40pub use string_methods::MethodFunction;
42
43#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
45pub enum FunctionCategory {
46 Constant, Mathematical, Statistical, Astronomical, Chemical, Date, String, Aggregate, Conversion, BigNumber, TableFunction, }
58
59impl fmt::Display for FunctionCategory {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 match self {
62 FunctionCategory::Constant => write!(f, "Constant"),
63 FunctionCategory::Mathematical => write!(f, "Mathematical"),
64 FunctionCategory::Statistical => write!(f, "Statistical"),
65 FunctionCategory::Astronomical => write!(f, "Astronomical"),
66 FunctionCategory::Chemical => write!(f, "Chemical"),
67 FunctionCategory::Date => write!(f, "Date"),
68 FunctionCategory::String => write!(f, "String"),
69 FunctionCategory::Aggregate => write!(f, "Aggregate"),
70 FunctionCategory::Conversion => write!(f, "Conversion"),
71 FunctionCategory::BigNumber => write!(f, "BigNumber"),
72 FunctionCategory::TableFunction => write!(f, "TableFunction"),
73 }
74 }
75}
76
77#[derive(Debug, Clone)]
79pub enum ArgCount {
80 Fixed(usize),
82 Range(usize, usize),
84 Variadic,
86}
87
88impl ArgCount {
89 #[must_use]
90 pub fn is_valid(&self, count: usize) -> bool {
91 match self {
92 ArgCount::Fixed(n) => count == *n,
93 ArgCount::Range(min, max) => count >= *min && count <= *max,
94 ArgCount::Variadic => true,
95 }
96 }
97
98 #[must_use]
99 pub fn description(&self) -> String {
100 match self {
101 ArgCount::Fixed(0) => "no arguments".to_string(),
102 ArgCount::Fixed(1) => "1 argument".to_string(),
103 ArgCount::Fixed(n) => format!("{n} arguments"),
104 ArgCount::Range(min, max) => format!("{min} to {max} arguments"),
105 ArgCount::Variadic => "any number of arguments".to_string(),
106 }
107 }
108}
109
110#[derive(Debug, Clone)]
112pub struct FunctionSignature {
113 pub name: &'static str,
114 pub category: FunctionCategory,
115 pub arg_count: ArgCount,
116 pub description: &'static str,
117 pub returns: &'static str,
118 pub examples: Vec<&'static str>,
119}
120
121pub trait SqlFunction: Send + Sync {
123 fn signature(&self) -> FunctionSignature;
125
126 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue>;
128
129 fn validate_args(&self, args: &[DataValue]) -> Result<()> {
131 let sig = self.signature();
132 if !sig.arg_count.is_valid(args.len()) {
133 return Err(anyhow!(
134 "{}() expects {}, got {}",
135 sig.name,
136 sig.arg_count.description(),
137 args.len()
138 ));
139 }
140 Ok(())
141 }
142}
143
144pub struct FunctionRegistry {
146 functions: HashMap<String, Box<dyn SqlFunction>>,
147 by_category: HashMap<FunctionCategory, Vec<String>>,
148 methods: HashMap<String, Arc<dyn MethodFunction>>,
149}
150
151impl FunctionRegistry {
152 #[must_use]
154 pub fn new() -> Self {
155 let mut registry = Self {
156 functions: HashMap::new(),
157 by_category: HashMap::new(),
158 methods: HashMap::new(),
159 };
160
161 registry.register_constants();
163 registry.register_astronomical_functions();
164 registry.register_chemical_functions();
165 registry.register_mathematical_functions();
166 registry.register_statistical_functions();
167 registry.register_geometry_functions();
168 registry.register_physics_functions();
169 registry.register_date_time_functions();
170 registry.register_string_methods();
171 registry.register_financial_functions();
172 registry.register_bigint_functions();
173 registry.register_conversion_functions();
174 registry.register_hash_functions();
175 registry.register_comparison_functions();
176 registry.register_aggregate_functions();
177 registry.register_random_functions();
178 registry.register_format_functions();
179 registry.register_type_checking_functions();
180
181 registry
182 }
183
184 pub fn register(&mut self, func: Box<dyn SqlFunction>) {
186 let sig = func.signature();
187 let name = sig.name.to_uppercase();
188 let category = sig.category;
189
190 self.functions.insert(name.clone(), func);
192
193 self.by_category.entry(category).or_default().push(name);
195 }
196
197 #[must_use]
199 pub fn get(&self, name: &str) -> Option<&dyn SqlFunction> {
200 self.functions
201 .get(&name.to_uppercase())
202 .map(std::convert::AsRef::as_ref)
203 }
204
205 #[must_use]
207 pub fn contains(&self, name: &str) -> bool {
208 self.functions.contains_key(&name.to_uppercase())
209 }
210
211 #[must_use]
213 pub fn autocomplete(&self, prefix: &str) -> Vec<FunctionSignature> {
214 let prefix_upper = prefix.to_uppercase();
215 self.functions
216 .iter()
217 .filter(|(name, _)| name.starts_with(&prefix_upper))
218 .map(|(_, func)| func.signature())
219 .collect()
220 }
221
222 #[must_use]
224 pub fn get_by_category(&self, category: FunctionCategory) -> Vec<FunctionSignature> {
225 self.by_category
226 .get(&category)
227 .map(|names| {
228 names
229 .iter()
230 .filter_map(|name| self.functions.get(name))
231 .map(|func| func.signature())
232 .collect()
233 })
234 .unwrap_or_default()
235 }
236
237 #[must_use]
239 pub fn all_functions(&self) -> Vec<FunctionSignature> {
240 self.functions
241 .values()
242 .map(|func| func.signature())
243 .collect()
244 }
245
246 pub fn register_method(&mut self, method: Arc<dyn MethodFunction>) {
248 let method_name = method.method_name().to_uppercase();
249 self.methods.insert(method_name, method);
250 }
251
252 #[must_use]
254 pub fn get_method(&self, name: &str) -> Option<Arc<dyn MethodFunction>> {
255 if let Some(method) = self.methods.get(&name.to_uppercase()) {
257 return Some(Arc::clone(method));
258 }
259
260 for method in self.methods.values() {
262 if method.handles_method(name) {
263 return Some(Arc::clone(method));
264 }
265 }
266
267 None
268 }
269
270 #[must_use]
272 pub fn has_method(&self, name: &str) -> bool {
273 self.get_method(name).is_some()
274 }
275
276 #[must_use]
278 pub fn generate_markdown_docs(&self) -> String {
279 use std::fmt::Write;
280 let mut doc = String::new();
281
282 writeln!(&mut doc, "# SQL CLI Function Reference\n").unwrap();
283 writeln!(
284 &mut doc,
285 "This document is auto-generated from the function registry.\n"
286 )
287 .unwrap();
288
289 let mut categories: Vec<FunctionCategory> = self.by_category.keys().copied().collect();
291 categories.sort_by_key(|c| format!("{c:?}"));
292
293 for category in categories {
294 let functions = self.get_by_category(category);
295 if functions.is_empty() {
296 continue;
297 }
298
299 writeln!(&mut doc, "## {category} Functions\n").unwrap();
300
301 let mut functions = functions;
303 functions.sort_by_key(|f| f.name);
304
305 for func in functions {
306 writeln!(&mut doc, "### {}()\n", func.name).unwrap();
307 writeln!(&mut doc, "**Description:** {}\n", func.description).unwrap();
308 writeln!(
309 &mut doc,
310 "**Arguments:** {}\n",
311 func.arg_count.description()
312 )
313 .unwrap();
314 writeln!(&mut doc, "**Returns:** {}\n", func.returns).unwrap();
315
316 if !func.examples.is_empty() {
317 writeln!(&mut doc, "**Examples:**").unwrap();
318 writeln!(&mut doc, "```sql").unwrap();
319 for example in &func.examples {
320 writeln!(&mut doc, "{example}").unwrap();
321 }
322 writeln!(&mut doc, "```\n").unwrap();
323 }
324 }
325 }
326
327 doc
328 }
329
330 #[must_use]
332 pub fn generate_function_help(&self, name: &str) -> Option<String> {
333 self.get(name).map(|func| {
334 let sig = func.signature();
335 let mut help = String::new();
336 use std::fmt::Write;
337
338 writeln!(&mut help, "Function: {}()", sig.name).unwrap();
339 writeln!(&mut help, "Category: {}", sig.category).unwrap();
340 writeln!(&mut help, "Description: {}", sig.description).unwrap();
341 writeln!(&mut help, "Arguments: {}", sig.arg_count.description()).unwrap();
342 writeln!(&mut help, "Returns: {}", sig.returns).unwrap();
343
344 if !sig.examples.is_empty() {
345 writeln!(&mut help, "\nExamples:").unwrap();
346 for example in &sig.examples {
347 writeln!(&mut help, " {example}").unwrap();
348 }
349 }
350
351 help
352 })
353 }
354
355 #[must_use]
357 pub fn list_functions(&self) -> String {
358 use std::fmt::Write;
359 let mut list = String::new();
360
361 writeln!(&mut list, "Available SQL Functions:\n").unwrap();
362
363 let mut categories: Vec<FunctionCategory> = self.by_category.keys().copied().collect();
364 categories.sort_by_key(|c| format!("{c:?}"));
365
366 for category in categories {
367 let functions = self.get_by_category(category);
368 if functions.is_empty() {
369 continue;
370 }
371
372 writeln!(&mut list, "{category} Functions:").unwrap();
373
374 let mut functions = functions;
375 functions.sort_by_key(|f| f.name);
376
377 for func in functions {
378 writeln!(
379 &mut list,
380 " {:20} - {}",
381 format!("{}()", func.name),
382 func.description
383 )
384 .unwrap();
385 }
386 writeln!(&mut list).unwrap();
387 }
388
389 list
390 }
391
392 fn register_constants(&mut self) {
394 use constants::{
395 EFunction, HbarFunction, MassElectronFunction, MeFunction, PhiFunction, PiFunction,
396 TauFunction,
397 };
398
399 self.register(Box::new(PiFunction));
400 self.register(Box::new(EFunction));
401 self.register(Box::new(MeFunction)); self.register(Box::new(MassElectronFunction)); self.register(Box::new(TauFunction));
404 self.register(Box::new(PhiFunction));
405 self.register(Box::new(HbarFunction));
406 }
407
408 fn register_astronomical_functions(&mut self) {
410 use astronomy::{
411 AuFunction, DistJupiterFunction, DistMarsFunction, DistMercuryFunction,
412 DistNeptuneFunction, DistSaturnFunction, DistUranusFunction, DistVenusFunction,
413 LightYearFunction, MassEarthFunction, MassJupiterFunction, MassMarsFunction,
414 MassMercuryFunction, MassMoonFunction, MassNeptuneFunction, MassSaturnFunction,
415 MassSunFunction, MassUranusFunction, MassVenusFunction, ParsecFunction,
416 RadiusEarthFunction, RadiusJupiterFunction, RadiusMarsFunction, RadiusMercuryFunction,
417 RadiusMoonFunction, RadiusNeptuneFunction, RadiusSaturnFunction, RadiusSunFunction,
418 RadiusUranusFunction, RadiusVenusFunction,
419 };
420
421 use solar_system::{
422 DensitySolarBodyFunction, DistanceSolarBodyFunction, EscapeVelocitySolarBodyFunction,
423 GravitySolarBodyFunction, MassSolarBodyFunction, MoonsSolarBodyFunction,
424 OrbitalPeriodSolarBodyFunction, RadiusSolarBodyFunction,
425 RotationPeriodSolarBodyFunction,
426 };
427
428 self.register(Box::new(MassEarthFunction));
429 self.register(Box::new(MassSunFunction));
430 self.register(Box::new(MassMoonFunction));
431 self.register(Box::new(AuFunction)); self.register(Box::new(LightYearFunction));
433 self.register(Box::new(ParsecFunction));
434
435 self.register(Box::new(MassMercuryFunction));
437 self.register(Box::new(MassVenusFunction));
438 self.register(Box::new(MassMarsFunction));
439 self.register(Box::new(MassJupiterFunction));
440 self.register(Box::new(MassSaturnFunction));
441 self.register(Box::new(MassUranusFunction));
442 self.register(Box::new(MassNeptuneFunction));
443
444 self.register(Box::new(RadiusSunFunction));
446 self.register(Box::new(RadiusEarthFunction));
447 self.register(Box::new(RadiusMoonFunction));
448 self.register(Box::new(RadiusMercuryFunction));
449 self.register(Box::new(RadiusVenusFunction));
450 self.register(Box::new(RadiusMarsFunction));
451 self.register(Box::new(RadiusJupiterFunction));
452 self.register(Box::new(RadiusSaturnFunction));
453 self.register(Box::new(RadiusUranusFunction));
454 self.register(Box::new(RadiusNeptuneFunction));
455
456 self.register(Box::new(DistMercuryFunction));
458 self.register(Box::new(DistVenusFunction));
459 self.register(Box::new(DistMarsFunction));
460 self.register(Box::new(DistJupiterFunction));
461 self.register(Box::new(DistSaturnFunction));
462 self.register(Box::new(DistUranusFunction));
463 self.register(Box::new(DistNeptuneFunction));
464
465 self.register(Box::new(MassSolarBodyFunction));
467 self.register(Box::new(RadiusSolarBodyFunction));
468 self.register(Box::new(DistanceSolarBodyFunction));
469 self.register(Box::new(OrbitalPeriodSolarBodyFunction));
470 self.register(Box::new(GravitySolarBodyFunction));
471 self.register(Box::new(DensitySolarBodyFunction));
472 self.register(Box::new(EscapeVelocitySolarBodyFunction));
473 self.register(Box::new(RotationPeriodSolarBodyFunction));
474 self.register(Box::new(MoonsSolarBodyFunction));
475 }
476
477 fn register_chemical_functions(&mut self) {
479 use chemistry::{
480 AtomicMassFunction, AtomicNumberFunction, AvogadroFunction, MoleculeFormulaFunction,
481 NeutronsFunction,
482 };
483
484 self.register(Box::new(AvogadroFunction));
485 self.register(Box::new(AtomicMassFunction));
486 self.register(Box::new(AtomicNumberFunction));
487 self.register(Box::new(NeutronsFunction));
488 self.register(Box::new(MoleculeFormulaFunction));
489 }
490
491 fn register_string_methods(&mut self) {
493 use case_convert::{
494 ToCamelCaseFunction, ToConstantCaseFunction, ToKebabCaseFunction, ToPascalCaseFunction,
495 ToSnakeCaseFunction,
496 };
497 use number_words::{ToOrdinal, ToOrdinalWords, ToWords};
498 use string_fun::{
499 InitCapFunction, MorseCodeFunction, PigLatinFunction, ProperFunction, ReverseFunction,
500 Rot13Function, ScrambleFunction, SoundexFunction,
501 };
502 use string_utils::{LPadFunction, RPadFunction, RepeatFunction};
503 use text_processing::{CleanText, ExtractWords, StripPunctuation, Tokenize, WordCount};
504
505 string_methods::register_string_methods(self);
506
507 self.register(Box::new(RepeatFunction));
509 self.register(Box::new(LPadFunction));
510 self.register(Box::new(RPadFunction));
511
512 self.register(Box::new(ToSnakeCaseFunction));
514 self.register(Box::new(ToCamelCaseFunction));
515 self.register(Box::new(ToPascalCaseFunction));
516 self.register(Box::new(ToKebabCaseFunction));
517 self.register(Box::new(ToConstantCaseFunction));
518
519 self.register(Box::new(ReverseFunction));
521 self.register(Box::new(InitCapFunction));
522 self.register(Box::new(ProperFunction));
523 self.register(Box::new(Rot13Function));
524 self.register(Box::new(SoundexFunction));
525 self.register(Box::new(PigLatinFunction));
526 self.register(Box::new(MorseCodeFunction));
527 self.register(Box::new(ScrambleFunction));
528
529 self.register(Box::new(ToWords));
531 self.register(Box::new(ToOrdinal));
532 self.register(Box::new(ToOrdinalWords));
533
534 self.register(Box::new(StripPunctuation));
536 self.register(Box::new(Tokenize));
537 self.register(Box::new(CleanText));
538 self.register(Box::new(ExtractWords));
539 self.register(Box::new(WordCount));
540 }
541
542 fn register_geometry_functions(&mut self) {
544 use geometry::{
545 CircleAreaFunction, CircleCircumferenceFunction, Distance2DFunction,
546 PythagorasFunction, SphereSurfaceAreaFunction, SphereVolumeFunction,
547 TriangleAreaFunction,
548 };
549
550 self.register(Box::new(PythagorasFunction));
551 self.register(Box::new(CircleAreaFunction));
552 self.register(Box::new(CircleCircumferenceFunction));
553 self.register(Box::new(SphereVolumeFunction));
554 self.register(Box::new(SphereSurfaceAreaFunction));
555 self.register(Box::new(TriangleAreaFunction));
556 self.register(Box::new(Distance2DFunction));
557 }
558
559 fn register_hash_functions(&mut self) {
561 use hash::{Md5Function, Sha1Function, Sha256Function, Sha512Function};
562
563 self.register(Box::new(Md5Function));
564 self.register(Box::new(Sha1Function));
565 self.register(Box::new(Sha256Function));
566 self.register(Box::new(Sha512Function));
567 }
568
569 fn register_comparison_functions(&mut self) {
571 comparison::register_comparison_functions(self);
572 }
573
574 fn register_mathematical_functions(&mut self) {
576 use base_conversion::{
577 FromBase, FromBinary, FromHex, FromOctal, ToBase, ToBinary, ToHex, ToOctal,
578 };
579 use integer_limits::{
580 ByteMax, ByteMin, CharMax, CharMin, Int16Max, Int16Min, Int32Max, Int32Min, Int64Max,
581 Int64Min, Int8Max, Int8Min, IntMax, IntMin, LongMax, LongMin, ShortMax, ShortMin,
582 Uint16Max, Uint32Max, Uint8Max,
583 };
584 use mathematics::{
585 IsPrimeFunction, NextPrimeFunction, NthPrimeFunction, PrevPrimeFunction,
586 PrimeCountFunction, PrimeFunction, PrimePiFunction,
587 };
588 use trigonometry::{
589 AcosFunction, AsinFunction, Atan2Function, AtanFunction, CosFunction, CoshFunction,
590 CotFunction, SinFunction, SinhFunction, TanFunction, TanhFunction,
591 };
592
593 self.register(Box::new(PrimeFunction));
595 self.register(Box::new(NthPrimeFunction)); self.register(Box::new(IsPrimeFunction));
597 self.register(Box::new(PrimeCountFunction));
598 self.register(Box::new(PrimePiFunction)); self.register(Box::new(NextPrimeFunction));
600 self.register(Box::new(PrevPrimeFunction));
601
602 self.register(Box::new(SinFunction));
604 self.register(Box::new(CosFunction));
605 self.register(Box::new(TanFunction));
606 self.register(Box::new(CotFunction));
607 self.register(Box::new(AsinFunction));
608 self.register(Box::new(AcosFunction));
609 self.register(Box::new(AtanFunction));
610 self.register(Box::new(Atan2Function));
611
612 self.register(Box::new(SinhFunction));
614 self.register(Box::new(CoshFunction));
615 self.register(Box::new(TanhFunction));
616
617 self.register(Box::new(ToBase));
619 self.register(Box::new(FromBase));
620 self.register(Box::new(ToBinary));
621 self.register(Box::new(FromBinary));
622 self.register(Box::new(ToHex));
623 self.register(Box::new(FromHex));
624 self.register(Box::new(ToOctal));
625 self.register(Box::new(FromOctal));
626
627 self.register(Box::new(Int8Min));
629 self.register(Box::new(Int8Max));
630 self.register(Box::new(Uint8Max));
631 self.register(Box::new(Int16Min));
632 self.register(Box::new(Int16Max));
633 self.register(Box::new(Uint16Max));
634 self.register(Box::new(Int32Min));
635 self.register(Box::new(Int32Max));
636 self.register(Box::new(Uint32Max));
637 self.register(Box::new(Int64Min));
638 self.register(Box::new(Int64Max));
639
640 self.register(Box::new(ByteMin));
642 self.register(Box::new(ByteMax));
643 self.register(Box::new(CharMin));
644 self.register(Box::new(CharMax));
645 self.register(Box::new(ShortMin));
646 self.register(Box::new(ShortMax));
647 self.register(Box::new(IntMin));
648 self.register(Box::new(IntMax));
649 self.register(Box::new(LongMin));
650 self.register(Box::new(LongMax));
651
652 math::register_math_functions(self);
654 }
655
656 fn register_physics_functions(&mut self) {
658 physics::register_physics_functions(self);
659
660 use particle_charges::{
662 ChargeDownQuarkFunction, ChargeElectronFunction, ChargeMuonFunction,
663 ChargeNeutronFunction, ChargePositronFunction, ChargeProtonFunction, ChargeTauFunction,
664 ChargeUpQuarkFunction,
665 };
666
667 self.register(Box::new(ChargeElectronFunction));
668 self.register(Box::new(ChargeProtonFunction));
669 self.register(Box::new(ChargeNeutronFunction));
670 self.register(Box::new(ChargeUpQuarkFunction));
671 self.register(Box::new(ChargeDownQuarkFunction));
672 self.register(Box::new(ChargePositronFunction));
673 self.register(Box::new(ChargeMuonFunction));
674 self.register(Box::new(ChargeTauFunction));
675 }
676
677 fn register_date_time_functions(&mut self) {
679 date_time::register_date_time_functions(self);
680 }
681
682 fn register_financial_functions(&mut self) {
684 financial::register_financial_functions(self);
685 }
686
687 fn register_conversion_functions(&mut self) {
689 use convert::ConvertFunction;
690 use roman::{FromRoman, ToRoman};
691
692 self.register(Box::new(ConvertFunction));
693 self.register(Box::new(ToRoman));
694 self.register(Box::new(FromRoman));
695 }
696
697 fn register_statistical_functions(&mut self) {
699 use statistics::{
700 CorrelationFunction, KurtosisFunction, MedianFunction, ModeFunction,
701 PercentileFunction, SkewFunction, VarPopFunction, VarSampFunction, VarianceFunction,
702 };
703
704 self.register(Box::new(MedianFunction));
705 self.register(Box::new(PercentileFunction));
706 self.register(Box::new(ModeFunction));
707 self.register(Box::new(VarianceFunction));
708 self.register(Box::new(VarSampFunction));
709 self.register(Box::new(VarPopFunction));
710 self.register(Box::new(CorrelationFunction));
711 self.register(Box::new(SkewFunction));
712 self.register(Box::new(KurtosisFunction));
713 }
714
715 fn register_aggregate_functions(&mut self) {
717 use group_num::GroupNumFunction;
718
719 self.register(Box::new(GroupNumFunction::new()));
722 }
723
724 fn register_random_functions(&mut self) {
726 use random::{RandIntFunction, RandRangeFunction, RandomFunction};
727
728 self.register(Box::new(RandomFunction));
729 self.register(Box::new(RandIntFunction));
730 self.register(Box::new(RandRangeFunction));
731 }
732
733 fn register_format_functions(&mut self) {
735 use format::{
736 CenterFunction, FormatDateFunction, FormatNumberFunction, LPadFunction, RPadFunction,
737 };
738 use format_number::{FormatCurrencyFunction, RenderNumberFunction};
739
740 self.register(Box::new(FormatNumberFunction));
741 self.register(Box::new(FormatDateFunction));
742 self.register(Box::new(LPadFunction));
743 self.register(Box::new(RPadFunction));
744 self.register(Box::new(CenterFunction));
745 self.register(Box::new(RenderNumberFunction));
746 self.register(Box::new(FormatCurrencyFunction));
747 }
748
749 fn register_type_checking_functions(&mut self) {
751 use type_checking::{
752 IsBoolFunction, IsDateFunction, IsFloatFunction, IsIntegerFunction, IsNotNullFunction,
753 IsNullFunction, IsNumericFunction,
754 };
755
756 self.register(Box::new(IsDateFunction));
757 self.register(Box::new(IsBoolFunction));
758 self.register(Box::new(IsNumericFunction));
759 self.register(Box::new(IsIntegerFunction));
760 self.register(Box::new(IsFloatFunction));
761 self.register(Box::new(IsNullFunction));
762 self.register(Box::new(IsNotNullFunction));
763 }
764
765 fn register_bigint_functions(&mut self) {
767 use bigint::{
768 BigAddFunction, BigFactorialFunction, BigIntFunction, BigMulFunction, BigPowFunction,
769 BitAndFunction, BitOrFunction, BitShiftFunction, BitXorFunction, FromBinaryFunction,
770 FromHexFunction, ToBinaryFunction, ToHexFunction,
771 };
772
773 self.register(Box::new(BigIntFunction));
775 self.register(Box::new(BigAddFunction));
776 self.register(Box::new(BigMulFunction));
777 self.register(Box::new(BigPowFunction));
778 self.register(Box::new(BigFactorialFunction));
779
780 self.register(Box::new(BitAndFunction));
782 self.register(Box::new(BitOrFunction));
783 self.register(Box::new(BitXorFunction));
784 self.register(Box::new(BitShiftFunction));
785
786 self.register(Box::new(ToBinaryFunction));
788 self.register(Box::new(FromBinaryFunction));
789 self.register(Box::new(ToHexFunction));
790 self.register(Box::new(FromHexFunction));
791 }
792}
793
794impl Default for FunctionRegistry {
795 fn default() -> Self {
796 Self::new()
797 }
798}
799
800#[cfg(test)]
801mod tests {
802 use super::*;
803
804 #[test]
805 fn test_registry_creation() {
806 let registry = FunctionRegistry::new();
807
808 assert!(registry.contains("PI"));
810 assert!(registry.contains("MASS_EARTH"));
811 assert!(registry.contains("ME"));
812 }
813
814 #[test]
815 fn test_case_insensitive_lookup() {
816 let registry = FunctionRegistry::new();
817
818 assert!(registry.get("pi").is_some());
819 assert!(registry.get("PI").is_some());
820 assert!(registry.get("Pi").is_some());
821 }
822
823 #[test]
824 fn test_autocomplete() {
825 let registry = FunctionRegistry::new();
826
827 let mass_functions = registry.autocomplete("MASS");
828 assert!(!mass_functions.is_empty());
829
830 let names: Vec<&str> = mass_functions.iter().map(|sig| sig.name).collect();
832 assert!(names.contains(&"MASS_EARTH"));
833 assert!(names.contains(&"MASS_SUN"));
834 }
835}