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