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