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