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, PiFunction,
403 TauFunction,
404 };
405
406 self.register(Box::new(PiFunction));
407 self.register(Box::new(EFunction));
408 self.register(Box::new(MeFunction)); self.register(Box::new(MassElectronFunction)); self.register(Box::new(TauFunction));
411 self.register(Box::new(PhiFunction));
412 self.register(Box::new(HbarFunction));
413 }
414
415 fn register_astronomical_functions(&mut self) {
417 use astronomy::{
418 AuFunction, DistJupiterFunction, DistMarsFunction, DistMercuryFunction,
419 DistNeptuneFunction, DistSaturnFunction, DistUranusFunction, DistVenusFunction,
420 LightYearFunction, MassEarthFunction, MassJupiterFunction, MassMarsFunction,
421 MassMercuryFunction, MassMoonFunction, MassNeptuneFunction, MassSaturnFunction,
422 MassSunFunction, MassUranusFunction, MassVenusFunction, ParsecFunction,
423 RadiusEarthFunction, RadiusJupiterFunction, RadiusMarsFunction, RadiusMercuryFunction,
424 RadiusMoonFunction, RadiusNeptuneFunction, RadiusSaturnFunction, RadiusSunFunction,
425 RadiusUranusFunction, RadiusVenusFunction,
426 };
427
428 use solar_system::{
429 DensitySolarBodyFunction, DistanceSolarBodyFunction, EscapeVelocitySolarBodyFunction,
430 GravitySolarBodyFunction, MassSolarBodyFunction, MoonsSolarBodyFunction,
431 OrbitalPeriodSolarBodyFunction, RadiusSolarBodyFunction,
432 RotationPeriodSolarBodyFunction,
433 };
434
435 self.register(Box::new(MassEarthFunction));
436 self.register(Box::new(MassSunFunction));
437 self.register(Box::new(MassMoonFunction));
438 self.register(Box::new(AuFunction)); self.register(Box::new(LightYearFunction));
440 self.register(Box::new(ParsecFunction));
441
442 self.register(Box::new(MassMercuryFunction));
444 self.register(Box::new(MassVenusFunction));
445 self.register(Box::new(MassMarsFunction));
446 self.register(Box::new(MassJupiterFunction));
447 self.register(Box::new(MassSaturnFunction));
448 self.register(Box::new(MassUranusFunction));
449 self.register(Box::new(MassNeptuneFunction));
450
451 self.register(Box::new(RadiusSunFunction));
453 self.register(Box::new(RadiusEarthFunction));
454 self.register(Box::new(RadiusMoonFunction));
455 self.register(Box::new(RadiusMercuryFunction));
456 self.register(Box::new(RadiusVenusFunction));
457 self.register(Box::new(RadiusMarsFunction));
458 self.register(Box::new(RadiusJupiterFunction));
459 self.register(Box::new(RadiusSaturnFunction));
460 self.register(Box::new(RadiusUranusFunction));
461 self.register(Box::new(RadiusNeptuneFunction));
462
463 self.register(Box::new(DistMercuryFunction));
465 self.register(Box::new(DistVenusFunction));
466 self.register(Box::new(DistMarsFunction));
467 self.register(Box::new(DistJupiterFunction));
468 self.register(Box::new(DistSaturnFunction));
469 self.register(Box::new(DistUranusFunction));
470 self.register(Box::new(DistNeptuneFunction));
471
472 self.register(Box::new(MassSolarBodyFunction));
474 self.register(Box::new(RadiusSolarBodyFunction));
475 self.register(Box::new(DistanceSolarBodyFunction));
476 self.register(Box::new(OrbitalPeriodSolarBodyFunction));
477 self.register(Box::new(GravitySolarBodyFunction));
478 self.register(Box::new(DensitySolarBodyFunction));
479 self.register(Box::new(EscapeVelocitySolarBodyFunction));
480 self.register(Box::new(RotationPeriodSolarBodyFunction));
481 self.register(Box::new(MoonsSolarBodyFunction));
482 }
483
484 fn register_chemical_functions(&mut self) {
486 use chemistry::{
487 AtomicMassFunction, AtomicNumberFunction, AvogadroFunction, MoleculeFormulaFunction,
488 NeutronsFunction,
489 };
490
491 self.register(Box::new(AvogadroFunction));
492 self.register(Box::new(AtomicMassFunction));
493 self.register(Box::new(AtomicNumberFunction));
494 self.register(Box::new(NeutronsFunction));
495 self.register(Box::new(MoleculeFormulaFunction));
496 }
497
498 fn register_string_methods(&mut self) {
500 use case_convert::{
501 ToCamelCaseFunction, ToConstantCaseFunction, ToKebabCaseFunction, ToPascalCaseFunction,
502 ToSnakeCaseFunction,
503 };
504 use number_words::{ToOrdinal, ToOrdinalWords, ToWords};
505 use string_fun::{
506 InitCapFunction, MorseCodeFunction, PigLatinFunction, ProperFunction, ReverseFunction,
507 Rot13Function, ScrambleFunction, SoundexFunction,
508 };
509 use string_utils::{LPadFunction, RPadFunction, RepeatFunction};
510 use text_processing::{CleanText, ExtractWords, StripPunctuation, Tokenize, WordCount};
511
512 string_methods::register_string_methods(self);
513
514 self.register(Box::new(RepeatFunction));
516 self.register(Box::new(LPadFunction));
517 self.register(Box::new(RPadFunction));
518
519 self.register(Box::new(ToSnakeCaseFunction));
521 self.register(Box::new(ToCamelCaseFunction));
522 self.register(Box::new(ToPascalCaseFunction));
523 self.register(Box::new(ToKebabCaseFunction));
524 self.register(Box::new(ToConstantCaseFunction));
525
526 self.register(Box::new(ReverseFunction));
528 self.register(Box::new(InitCapFunction));
529 self.register(Box::new(ProperFunction));
530 self.register(Box::new(Rot13Function));
531 self.register(Box::new(SoundexFunction));
532 self.register(Box::new(PigLatinFunction));
533 self.register(Box::new(MorseCodeFunction));
534 self.register(Box::new(ScrambleFunction));
535
536 self.register(Box::new(ToWords));
538 self.register(Box::new(ToOrdinal));
539 self.register(Box::new(ToOrdinalWords));
540
541 self.register(Box::new(StripPunctuation));
543 self.register(Box::new(Tokenize));
544 self.register(Box::new(CleanText));
545 self.register(Box::new(ExtractWords));
546 self.register(Box::new(WordCount));
547 }
548
549 fn register_geometry_functions(&mut self) {
551 use geometry::{
552 CircleAreaFunction, CircleCircumferenceFunction, Distance2DFunction,
553 PythagorasFunction, SphereSurfaceAreaFunction, SphereVolumeFunction,
554 TriangleAreaFunction,
555 };
556
557 self.register(Box::new(PythagorasFunction));
558 self.register(Box::new(CircleAreaFunction));
559 self.register(Box::new(CircleCircumferenceFunction));
560 self.register(Box::new(SphereVolumeFunction));
561 self.register(Box::new(SphereSurfaceAreaFunction));
562 self.register(Box::new(TriangleAreaFunction));
563 self.register(Box::new(Distance2DFunction));
564 }
565
566 fn register_hash_functions(&mut self) {
568 use hash::{Md5Function, Sha1Function, Sha256Function, Sha512Function};
569
570 self.register(Box::new(Md5Function));
571 self.register(Box::new(Sha1Function));
572 self.register(Box::new(Sha256Function));
573 self.register(Box::new(Sha512Function));
574 }
575
576 fn register_comparison_functions(&mut self) {
578 comparison::register_comparison_functions(self);
579 }
580
581 fn register_mathematical_functions(&mut self) {
583 use base_conversion::{
584 FromBase, FromBinary, FromHex, FromOctal, ToBase, ToBinary, ToHex, ToOctal,
585 };
586 use integer_limits::{
587 ByteMax, ByteMin, CharMax, CharMin, Int16Max, Int16Min, Int32Max, Int32Min, Int64Max,
588 Int64Min, Int8Max, Int8Min, IntMax, IntMin, LongMax, LongMin, ShortMax, ShortMin,
589 Uint16Max, Uint32Max, Uint8Max,
590 };
591 use mathematics::{
592 IsPrimeFunction, NextPrimeFunction, NthPrimeFunction, PrevPrimeFunction,
593 PrimeCountFunction, PrimeFunction, PrimePiFunction,
594 };
595 use trigonometry::{
596 AcosFunction, AsinFunction, Atan2Function, AtanFunction, CosFunction, CoshFunction,
597 CotFunction, SinFunction, SinhFunction, TanFunction, TanhFunction,
598 };
599
600 self.register(Box::new(PrimeFunction));
602 self.register(Box::new(NthPrimeFunction)); self.register(Box::new(IsPrimeFunction));
604 self.register(Box::new(PrimeCountFunction));
605 self.register(Box::new(PrimePiFunction)); self.register(Box::new(NextPrimeFunction));
607 self.register(Box::new(PrevPrimeFunction));
608
609 self.register(Box::new(SinFunction));
611 self.register(Box::new(CosFunction));
612 self.register(Box::new(TanFunction));
613 self.register(Box::new(CotFunction));
614 self.register(Box::new(AsinFunction));
615 self.register(Box::new(AcosFunction));
616 self.register(Box::new(AtanFunction));
617 self.register(Box::new(Atan2Function));
618
619 self.register(Box::new(SinhFunction));
621 self.register(Box::new(CoshFunction));
622 self.register(Box::new(TanhFunction));
623
624 self.register(Box::new(ToBase));
626 self.register(Box::new(FromBase));
627 self.register(Box::new(ToBinary));
628 self.register(Box::new(FromBinary));
629 self.register(Box::new(ToHex));
630 self.register(Box::new(FromHex));
631 self.register(Box::new(ToOctal));
632 self.register(Box::new(FromOctal));
633
634 self.register(Box::new(Int8Min));
636 self.register(Box::new(Int8Max));
637 self.register(Box::new(Uint8Max));
638 self.register(Box::new(Int16Min));
639 self.register(Box::new(Int16Max));
640 self.register(Box::new(Uint16Max));
641 self.register(Box::new(Int32Min));
642 self.register(Box::new(Int32Max));
643 self.register(Box::new(Uint32Max));
644 self.register(Box::new(Int64Min));
645 self.register(Box::new(Int64Max));
646
647 self.register(Box::new(ByteMin));
649 self.register(Box::new(ByteMax));
650 self.register(Box::new(CharMin));
651 self.register(Box::new(CharMax));
652 self.register(Box::new(ShortMin));
653 self.register(Box::new(ShortMax));
654 self.register(Box::new(IntMin));
655 self.register(Box::new(IntMax));
656 self.register(Box::new(LongMin));
657 self.register(Box::new(LongMax));
658
659 math::register_math_functions(self);
661 }
662
663 fn register_physics_functions(&mut self) {
665 physics::register_physics_functions(self);
666
667 use particle_charges::{
669 ChargeDownQuarkFunction, ChargeElectronFunction, ChargeMuonFunction,
670 ChargeNeutronFunction, ChargePositronFunction, ChargeProtonFunction, ChargeTauFunction,
671 ChargeUpQuarkFunction,
672 };
673
674 self.register(Box::new(ChargeElectronFunction));
675 self.register(Box::new(ChargeProtonFunction));
676 self.register(Box::new(ChargeNeutronFunction));
677 self.register(Box::new(ChargeUpQuarkFunction));
678 self.register(Box::new(ChargeDownQuarkFunction));
679 self.register(Box::new(ChargePositronFunction));
680 self.register(Box::new(ChargeMuonFunction));
681 self.register(Box::new(ChargeTauFunction));
682 }
683
684 fn register_date_time_functions(&mut self) {
686 date_time::register_date_time_functions(self);
687 }
688
689 fn register_financial_functions(&mut self) {
691 financial::register_financial_functions(self);
692 }
693
694 fn register_conversion_functions(&mut self) {
696 use convert::ConvertFunction;
697 use roman::{FromRoman, ToRoman};
698
699 self.register(Box::new(ConvertFunction));
700 self.register(Box::new(ToRoman));
701 self.register(Box::new(FromRoman));
702 }
703
704 fn register_statistical_functions(&mut self) {
706 use statistics::{
707 CorrelationFunction, KurtosisFunction, MedianFunction, ModeFunction,
708 PercentileFunction, SkewFunction, VarPopFunction, VarSampFunction, VarianceFunction,
709 };
710
711 self.register(Box::new(MedianFunction));
712 self.register(Box::new(PercentileFunction));
713 self.register(Box::new(ModeFunction));
714 self.register(Box::new(VarianceFunction));
715 self.register(Box::new(VarSampFunction));
716 self.register(Box::new(VarPopFunction));
717 self.register(Box::new(CorrelationFunction));
718 self.register(Box::new(SkewFunction));
719 self.register(Box::new(KurtosisFunction));
720 }
721
722 fn register_aggregate_functions(&mut self) {
724 use group_num::GroupNumFunction;
725
726 self.register(Box::new(GroupNumFunction::new()));
729 }
730
731 fn register_random_functions(&mut self) {
733 use random::{RandIntFunction, RandRangeFunction, RandomFunction};
734
735 self.register(Box::new(RandomFunction));
736 self.register(Box::new(RandIntFunction));
737 self.register(Box::new(RandRangeFunction));
738 }
739
740 fn register_format_functions(&mut self) {
742 use format::{
743 CenterFunction, FormatDateFunction, FormatNumberFunction, LPadFunction, RPadFunction,
744 };
745 use format_number::{FormatCurrencyFunction, RenderNumberFunction};
746
747 self.register(Box::new(FormatNumberFunction));
748 self.register(Box::new(FormatDateFunction));
749 self.register(Box::new(LPadFunction));
750 self.register(Box::new(RPadFunction));
751 self.register(Box::new(CenterFunction));
752 self.register(Box::new(RenderNumberFunction));
753 self.register(Box::new(FormatCurrencyFunction));
754 }
755
756 fn register_type_checking_functions(&mut self) {
758 use type_checking::{
759 IsBoolFunction, IsDateFunction, IsFloatFunction, IsIntegerFunction, IsNotNullFunction,
760 IsNullFunction, IsNumericFunction,
761 };
762
763 self.register(Box::new(IsDateFunction));
764 self.register(Box::new(IsBoolFunction));
765 self.register(Box::new(IsNumericFunction));
766 self.register(Box::new(IsIntegerFunction));
767 self.register(Box::new(IsFloatFunction));
768 self.register(Box::new(IsNullFunction));
769 self.register(Box::new(IsNotNullFunction));
770 }
771
772 fn register_utility_functions(&mut self) {
774 use utility::{
775 AsciiFunction, CharFunction, DecodeFunction, EncodeFunction, OrdFunction,
776 ToDecimalFunction, ToIntFunction, ToStringFunction, UnicodeFunction,
777 };
778
779 self.register(Box::new(AsciiFunction));
780 self.register(Box::new(OrdFunction));
781 self.register(Box::new(CharFunction));
782 self.register(Box::new(ToIntFunction));
783 self.register(Box::new(ToDecimalFunction));
784 self.register(Box::new(ToStringFunction));
785 self.register(Box::new(EncodeFunction));
786 self.register(Box::new(DecodeFunction));
787 self.register(Box::new(UnicodeFunction));
788 }
789
790 fn register_bigint_functions(&mut self) {
792 use bigint::{
793 BigAddFunction, BigFactorialFunction, BigIntFunction, BigMulFunction, BigPowFunction,
794 BitAndFunction, BitOrFunction, BitShiftFunction, BitXorFunction, FromBinaryFunction,
795 FromHexFunction, ToBinaryFunction, ToHexFunction,
796 };
797
798 self.register(Box::new(BigIntFunction));
800 self.register(Box::new(BigAddFunction));
801 self.register(Box::new(BigMulFunction));
802 self.register(Box::new(BigPowFunction));
803 self.register(Box::new(BigFactorialFunction));
804
805 self.register(Box::new(BitAndFunction));
807 self.register(Box::new(BitOrFunction));
808 self.register(Box::new(BitXorFunction));
809 self.register(Box::new(BitShiftFunction));
810
811 self.register(Box::new(ToBinaryFunction));
813 self.register(Box::new(FromBinaryFunction));
814 self.register(Box::new(ToHexFunction));
815 self.register(Box::new(FromHexFunction));
816 }
817
818 fn register_bitwise_functions(&mut self) {
820 bitwise::register_bitwise_functions(self);
821
822 self.register(Box::new(bitwise_string::BitAndStr));
824 self.register(Box::new(bitwise_string::BitOrStr));
825 self.register(Box::new(bitwise_string::BitXorStr));
826 self.register(Box::new(bitwise_string::BitNotStr));
827 self.register(Box::new(bitwise_string::BitFlip));
828 self.register(Box::new(bitwise_string::BitCount));
829 self.register(Box::new(bitwise_string::BitRotateLeft));
830 self.register(Box::new(bitwise_string::BitRotateRight));
831 self.register(Box::new(bitwise_string::BitShiftLeft));
832 self.register(Box::new(bitwise_string::BitShiftRight));
833 self.register(Box::new(bitwise_string::HammingDistance));
834 }
835}
836
837impl Default for FunctionRegistry {
838 fn default() -> Self {
839 Self::new()
840 }
841}
842
843#[cfg(test)]
844mod tests {
845 use super::*;
846
847 #[test]
848 fn test_registry_creation() {
849 let registry = FunctionRegistry::new();
850
851 assert!(registry.contains("PI"));
853 assert!(registry.contains("MASS_EARTH"));
854 assert!(registry.contains("ME"));
855 }
856
857 #[test]
858 fn test_case_insensitive_lookup() {
859 let registry = FunctionRegistry::new();
860
861 assert!(registry.get("pi").is_some());
862 assert!(registry.get("PI").is_some());
863 assert!(registry.get("Pi").is_some());
864 }
865
866 #[test]
867 fn test_autocomplete() {
868 let registry = FunctionRegistry::new();
869
870 let mass_functions = registry.autocomplete("MASS");
871 assert!(!mass_functions.is_empty());
872
873 let names: Vec<&str> = mass_functions.iter().map(|sig| sig.name).collect();
875 assert!(names.contains(&"MASS_EARTH"));
876 assert!(names.contains(&"MASS_SUN"));
877 }
878}