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