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