rs_sci/
units.rs

1#[derive(Debug, Clone)]
2pub enum Unit {
3    Mass(Mass),
4    Time(Time),
5    Length(Length),
6    Speed(Speed),
7    Angle(Angle),
8    Pressure(Pressure),
9    Area(Area),
10    Volume(Volume),
11    Temperature(Temperature),
12    Energy(Energy),
13    Power(Power),
14    Force(Force),
15    ElectricCharge(ElectricCharge),
16    Current(Current),
17    Frequency(Frequency),
18    Acceleration(Acceleration),
19}
20
21#[derive(Debug, Clone)]
22pub enum Mass {
23    Kg,
24    Gram,
25    Ton,
26    Grain,
27    Carat,
28    Pound,
29    Ounce,
30    Atomic,
31    Earth,
32    Sun,
33    Moon,
34    Jupiter,
35    Milligram,
36    Microgram,
37    Nanogram,
38    Custom(f64, Box<Mass>),
39}
40
41impl Mass {
42    pub fn convert_to(self, to: Self) -> Self {
43        let base_kg = match self {
44            Mass::Kg => 1.0,
45            Mass::Gram => 0.001,
46            Mass::Ton => 1000.0,
47            Mass::Grain => 0.0000647989,
48            Mass::Carat => 0.0002,
49            Mass::Pound => 0.45359237,
50            Mass::Ounce => 0.028349523125,
51            Mass::Atomic => 1.660539067e-27,
52            Mass::Earth => 5.972e24,
53            Mass::Sun => 1.989e30,
54            Mass::Moon => 7.34767309e22,
55            Mass::Jupiter => 1.8982e27,
56            Mass::Milligram => 0.000001,
57            Mass::Microgram => 0.000000001,
58            Mass::Nanogram => 0.000000000001,
59            Mass::Custom(value, base) => {
60                value
61                    * match *base {
62                        Mass::Kg => 1.0,
63                        Mass::Gram => 0.001,
64                        Mass::Ton => 1000.0,
65                        Mass::Grain => 0.0000647989,
66                        Mass::Carat => 0.0002,
67                        Mass::Pound => 0.45359237,
68                        Mass::Ounce => 0.028349523125,
69                        Mass::Atomic => 1.660539067e-27,
70                        Mass::Earth => 5.972e24,
71                        Mass::Sun => 1.989e30,
72                        Mass::Moon => 7.34767309e22,
73                        Mass::Jupiter => 1.8982e27,
74                        Mass::Milligram => 0.000001,
75                        Mass::Microgram => 0.000000001,
76                        Mass::Nanogram => 0.000000000001,
77                        Mass::Custom(v, b) => v * b.convert_to(Mass::Kg).to_kg(),
78                    }
79            }
80        };
81
82        match to {
83            Mass::Kg => Mass::Kg,
84            Mass::Gram => Mass::Custom(base_kg / 0.001, Box::new(Mass::Gram)),
85            Mass::Ton => Mass::Custom(base_kg / 1000.0, Box::new(Mass::Ton)),
86            Mass::Grain => Mass::Custom(base_kg / 0.0000647989, Box::new(Mass::Grain)),
87            Mass::Carat => Mass::Custom(base_kg / 0.0002, Box::new(Mass::Carat)),
88            Mass::Pound => Mass::Custom(base_kg / 0.45359237, Box::new(Mass::Pound)),
89            Mass::Ounce => Mass::Custom(base_kg / 0.028349523125, Box::new(Mass::Ounce)),
90            Mass::Atomic => Mass::Custom(base_kg / 1.660539067e-27, Box::new(Mass::Atomic)),
91            Mass::Earth => Mass::Custom(base_kg / 5.972e24, Box::new(Mass::Earth)),
92            Mass::Sun => Mass::Custom(base_kg / 1.989e30, Box::new(Mass::Sun)),
93            Mass::Moon => Mass::Custom(base_kg / 7.34767309e22, Box::new(Mass::Moon)),
94            Mass::Jupiter => Mass::Custom(base_kg / 1.8982e27, Box::new(Mass::Jupiter)),
95            Mass::Milligram => Mass::Custom(base_kg / 0.000001, Box::new(Mass::Milligram)),
96            Mass::Microgram => Mass::Custom(base_kg / 0.000000001, Box::new(Mass::Microgram)),
97            Mass::Nanogram => Mass::Custom(base_kg / 0.000000000001, Box::new(Mass::Nanogram)),
98            Mass::Custom(value, base) => {
99                let base_in_kg = base.clone().convert_to(Mass::Kg).to_kg();
100                Mass::Custom(base_kg / (value * base_in_kg), base)
101            }
102        }
103    }
104
105    pub fn to_kg(&self) -> f64 {
106        match self {
107            Mass::Kg => 1.0,
108            Mass::Gram => 0.001,
109            Mass::Ton => 1000.0,
110            Mass::Grain => 0.0000647989,
111            Mass::Carat => 0.0002,
112            Mass::Pound => 0.45359237,
113            Mass::Ounce => 0.028349523125,
114            Mass::Atomic => 1.660539067e-27,
115            Mass::Earth => 5.972e24,
116            Mass::Sun => 1.989e30,
117            Mass::Moon => 7.34767309e22,
118            Mass::Jupiter => 1.8982e27,
119            Mass::Milligram => 0.000001,
120            Mass::Microgram => 0.000000001,
121            Mass::Nanogram => 0.000000000001,
122            Mass::Custom(value, base) => value * base.to_kg(),
123        }
124    }
125}
126
127#[derive(Debug, Clone)]
128pub enum Time {
129    Second,
130    Millisecond,
131    Microsecond,
132    Nanosecond,
133    Minute,
134    Hour,
135    Day,
136    Week,
137    Year,
138    JulianYear,
139    Decade,
140    Century,
141    SiderealDay,
142    SiderealYear,
143    Custom(f64, Box<Time>),
144}
145
146impl Time {
147    pub fn convert_to(self, to: Self) -> Self {
148        let base_seconds = match self {
149            Time::Second => 1.0,
150            Time::Millisecond => 0.001,
151            Time::Microsecond => 0.000001,
152            Time::Nanosecond => 0.000000001,
153            Time::Minute => 60.0,
154            Time::Hour => 3600.0,
155            Time::Day => 86400.0,
156            Time::Week => 604800.0,
157            Time::Year => 31536000.0,
158            Time::JulianYear => 31557600.0,
159            Time::Decade => 315360000.0,
160            Time::Century => 3153600000.0,
161            Time::SiderealDay => 86164.0905,
162            Time::SiderealYear => 31558149.504,
163            Time::Custom(value, base) => {
164                value
165                    * match *base {
166                        Time::Second => 1.0,
167                        Time::Millisecond => 0.001,
168                        Time::Microsecond => 0.000001,
169                        Time::Nanosecond => 0.000000001,
170                        Time::Minute => 60.0,
171                        Time::Hour => 3600.0,
172                        Time::Day => 86400.0,
173                        Time::Week => 604800.0,
174                        Time::Year => 31536000.0,
175                        Time::JulianYear => 31557600.0,
176                        Time::Decade => 315360000.0,
177                        Time::Century => 3153600000.0,
178                        Time::SiderealDay => 86164.0905,
179                        Time::SiderealYear => 31558149.504,
180                        Time::Custom(v, b) => v * b.convert_to(Time::Second).to_seconds(),
181                    }
182            }
183        };
184
185        match to {
186            Time::Second => Time::Second,
187            Time::Millisecond => Time::Custom(base_seconds / 0.001, Box::new(Time::Millisecond)),
188            Time::Microsecond => Time::Custom(base_seconds / 0.000001, Box::new(Time::Microsecond)),
189            Time::Nanosecond => {
190                Time::Custom(base_seconds / 0.000000001, Box::new(Time::Nanosecond))
191            }
192            Time::Minute => Time::Custom(base_seconds / 60.0, Box::new(Time::Minute)),
193            Time::Hour => Time::Custom(base_seconds / 3600.0, Box::new(Time::Hour)),
194            Time::Day => Time::Custom(base_seconds / 86400.0, Box::new(Time::Day)),
195            Time::Week => Time::Custom(base_seconds / 604800.0, Box::new(Time::Week)),
196            Time::Year => Time::Custom(base_seconds / 31536000.0, Box::new(Time::Year)),
197            Time::JulianYear => Time::Custom(base_seconds / 31557600.0, Box::new(Time::JulianYear)),
198            Time::Decade => Time::Custom(base_seconds / 315360000.0, Box::new(Time::Decade)),
199            Time::Century => Time::Custom(base_seconds / 3153600000.0, Box::new(Time::Century)),
200            Time::SiderealDay => {
201                Time::Custom(base_seconds / 86164.0905, Box::new(Time::SiderealDay))
202            }
203            Time::SiderealYear => {
204                Time::Custom(base_seconds / 31558149.504, Box::new(Time::SiderealYear))
205            }
206            Time::Custom(value, base) => {
207                let base_in_seconds = base.clone().convert_to(Time::Second).to_seconds();
208                Time::Custom(base_seconds / (value * base_in_seconds), base)
209            }
210        }
211    }
212
213    pub fn to_seconds(&self) -> f64 {
214        match self {
215            Time::Second => 1.0,
216            Time::Millisecond => 0.001,
217            Time::Microsecond => 0.000001,
218            Time::Nanosecond => 0.000000001,
219            Time::Minute => 60.0,
220            Time::Hour => 3600.0,
221            Time::Day => 86400.0,
222            Time::Week => 604800.0,
223            Time::Year => 31536000.0,
224            Time::JulianYear => 31557600.0,
225            Time::Decade => 315360000.0,
226            Time::Century => 3153600000.0,
227            Time::SiderealDay => 86164.0905,
228            Time::SiderealYear => 31558149.504,
229            Time::Custom(value, base) => value * base.to_seconds(),
230        }
231    }
232}
233
234#[derive(Debug, Clone)]
235pub enum Length {
236    Meter,
237    Centimeter,
238    Kilometer,
239    Inch,
240    Foot,
241    Yard,
242    Mile,
243    Mil,
244    Point,
245    NauticalMile,
246    Fermi,
247    Micron,
248    AstroUnit,
249    LightYear,
250    LightMinute,
251    LightSecond,
252    LightDay,
253    Parsec,
254    Millimeter,
255    Micrometer,
256    Nanometer,
257    Angstrom,
258    Megaparsec,
259    Gigaparsec,
260    Custom(f64, Box<Length>),
261}
262
263impl Length {
264    pub fn convert_to(self, to: Self) -> Self {
265        let base_meters = self.to_meters();
266
267        match to {
268            Length::Meter => Length::Meter,
269            Length::Centimeter => Length::Custom(base_meters * 100.0, Box::new(Length::Centimeter)),
270            Length::Kilometer => Length::Custom(base_meters / 1000.0, Box::new(Length::Kilometer)),
271            Length::Inch => Length::Custom(base_meters / 0.0254, Box::new(Length::Inch)),
272            Length::Foot => Length::Custom(base_meters / 0.3048, Box::new(Length::Foot)),
273            Length::Yard => Length::Custom(base_meters / 0.9144, Box::new(Length::Yard)),
274            Length::Mile => Length::Custom(base_meters / 1609.344, Box::new(Length::Mile)),
275            Length::Mil => Length::Custom(base_meters / 0.0000254, Box::new(Length::Mil)),
276            Length::Point => Length::Custom(base_meters / 0.0003527777778, Box::new(Length::Point)),
277            Length::NauticalMile => {
278                Length::Custom(base_meters / 1852.0, Box::new(Length::NauticalMile))
279            }
280            Length::Fermi => Length::Custom(base_meters / 1e-15, Box::new(Length::Fermi)),
281            Length::Micron => Length::Custom(base_meters / 0.000001, Box::new(Length::Micron)),
282            Length::AstroUnit => {
283                Length::Custom(base_meters / 149597870700.0, Box::new(Length::AstroUnit))
284            }
285            Length::LightYear => {
286                Length::Custom(base_meters / 9.461e15, Box::new(Length::LightYear))
287            }
288            Length::LightMinute => {
289                Length::Custom(base_meters / 17987547480.0, Box::new(Length::LightMinute))
290            }
291            Length::LightSecond => {
292                Length::Custom(base_meters / 299792458.0, Box::new(Length::LightSecond))
293            }
294            Length::LightDay => {
295                Length::Custom(base_meters / 25902068371200.0, Box::new(Length::LightDay))
296            }
297            Length::Parsec => Length::Custom(base_meters / 3.086e16, Box::new(Length::Parsec)),
298            Length::Millimeter => Length::Custom(base_meters / 0.001, Box::new(Length::Millimeter)),
299            Length::Micrometer => {
300                Length::Custom(base_meters / 0.000001, Box::new(Length::Micrometer))
301            }
302            Length::Nanometer => {
303                Length::Custom(base_meters / 0.000000001, Box::new(Length::Nanometer))
304            }
305            Length::Angstrom => Length::Custom(base_meters / 1e-10, Box::new(Length::Angstrom)),
306            Length::Megaparsec => {
307                Length::Custom(base_meters / 3.086e22, Box::new(Length::Megaparsec))
308            }
309            Length::Gigaparsec => {
310                Length::Custom(base_meters / 3.086e25, Box::new(Length::Gigaparsec))
311            }
312            Length::Custom(value, base) => {
313                let base_in_meters = base.clone().convert_to(Length::Meter).to_meters();
314                Length::Custom(base_meters / (value * base_in_meters), base)
315            }
316        }
317    }
318
319    pub fn to_meters(&self) -> f64 {
320        match self {
321            Length::Meter => 1.0,
322            Length::Centimeter => 0.01,
323            Length::Kilometer => 1000.0,
324            Length::Inch => 0.0254,
325            Length::Foot => 0.3048,
326            Length::Yard => 0.9144,
327            Length::Mile => 1609.344,
328            Length::Mil => 0.0000254,
329            Length::Point => 0.0003527777778,
330            Length::NauticalMile => 1852.0,
331            Length::Fermi => 1e-15,
332            Length::Micron => 0.000001,
333            Length::AstroUnit => 149597870700.0,
334            Length::LightYear => 9.461e15,
335            Length::LightMinute => 17987547480.0,
336            Length::LightSecond => 299792458.0,
337            Length::LightDay => 25902068371200.0,
338            Length::Parsec => 3.086e16,
339            Length::Millimeter => 0.001,
340            Length::Micrometer => 0.000001,
341            Length::Nanometer => 0.000000001,
342            Length::Angstrom => 1e-10,
343            Length::Megaparsec => 3.086e22,
344            Length::Gigaparsec => 3.086e25,
345            Length::Custom(value, base) => value * base.to_meters(),
346        }
347    }
348}
349
350#[derive(Debug, Clone)]
351pub enum Speed {
352    KmH,
353    MpH,
354    Mach,
355    Knot,
356    MetersPerSecond,
357    C,
358    Custom(Length, Time),
359}
360
361impl Speed {
362    pub fn convert_to(self, to: Self) -> Self {
363        let base_mps = self.to_mps();
364
365        match to {
366            Speed::MetersPerSecond => Speed::MetersPerSecond,
367            Speed::KmH => {
368                let km_per_hour = base_mps * 3.6; // Convert m/s to km/h
369                Speed::Custom(
370                    Length::Custom(km_per_hour, Box::new(Length::Kilometer)),
371                    Time::Hour,
372                )
373            }
374            Speed::MpH => {
375                let miles_per_hour = base_mps * 2.23694; // Convert m/s to mph
376                Speed::Custom(
377                    Length::Custom(miles_per_hour, Box::new(Length::Mile)),
378                    Time::Hour,
379                )
380            }
381            Speed::Mach => {
382                let mach = base_mps / 343.0; // Convert m/s to Mach number
383                Speed::Custom(
384                    Length::Custom(mach * 343.0, Box::new(Length::Meter)),
385                    Time::Second,
386                )
387            }
388            Speed::Knot => {
389                let knots = base_mps * 1.94384; // Convert m/s to knots
390                Speed::Custom(
391                    Length::Custom(knots * 1852.0, Box::new(Length::NauticalMile)),
392                    Time::Hour,
393                )
394            }
395            Speed::C => {
396                let c = base_mps / 299792458.0; 
397                Speed::Custom(
398                    Length::Custom(c * 299792458.0, Box::new(Length::Meter)),
399                    Time::Second,
400                )
401            }
402            Speed::Custom(length, time) => {
403                let target_length = Length::Meter.convert_to(length);
404                let target_time = Time::Second.convert_to(time);
405                Speed::Custom(target_length, target_time)
406            }
407        }
408    }
409
410    pub fn to_mps(&self) -> f64 {
411        match self {
412            Speed::MetersPerSecond => 1.0,
413            Speed::KmH => 0.277778,
414            Speed::MpH => 0.44704,
415            Speed::Mach => 343.0,
416            Speed::Knot => 0.514444,
417            Speed::C => 299792458.0,
418            Speed::Custom(length, time) => {
419                let meters = match length {
420                    Length::Custom(value, base) => value * base.to_meters(),
421                    _ => length.clone().convert_to(Length::Meter).to_meters(),
422                };
423                let seconds = match time {
424                    Time::Custom(value, base) => value * base.to_seconds(),
425                    _ => time.clone().convert_to(Time::Second).to_seconds(),
426                };
427                meters / seconds
428            }
429        }
430    }
431
432    pub fn to_kmh(&self) -> f64 {
433        self.to_mps() * 3.6
434    }
435
436    pub fn to_mph(&self) -> f64 {
437        self.to_mps() * 2.23694
438    }
439
440    pub fn to_knots(&self) -> f64 {
441        self.to_mps() * 1.94384
442    }
443
444    pub fn to_mach(&self) -> f64 {
445        self.to_mps() / 343.0
446    }
447
448    pub fn to_c(&self) -> f64 {
449        self.to_mps() / 299792458.0
450    }
451}
452
453#[derive(Debug, Clone)]
454pub enum Angle {
455    Degree,
456    Radian,
457    Gradian,
458    ArcMinute,
459    ArcSecond,
460    Custom(f64, Box<Angle>),
461}
462
463impl Angle {
464    pub fn convert_to(self, to: Self) -> Self {
465        // Convert to radians as base unit
466        let base_radians = self.to_radians();
467
468        match to {
469            Angle::Radian => Angle::Radian,
470            Angle::Degree => {
471                Angle::Custom(base_radians * 57.29577951308232, Box::new(Angle::Degree))
472            } // 180/π
473            Angle::Gradian => {
474                Angle::Custom(base_radians * 63.66197723675813, Box::new(Angle::Gradian))
475            } // 200/π
476            Angle::ArcMinute => Angle::Custom(
477                base_radians * 3437.7467707849396,
478                Box::new(Angle::ArcMinute),
479            ), // 10800/π
480            Angle::ArcSecond => Angle::Custom(
481                base_radians * 206264.80624709636,
482                Box::new(Angle::ArcSecond),
483            ), // 648000/π
484            Angle::Custom(value, base) => {
485                let base_in_radians = base.clone().convert_to(Angle::Radian).to_radians();
486                Angle::Custom(base_radians / (value * base_in_radians), base)
487            }
488        }
489    }
490
491    pub fn to_radians(&self) -> f64 {
492        match self {
493            Angle::Radian => 1.0,
494            Angle::Degree => 0.017453292519943295,
495            Angle::Gradian => 0.015707963267948967,
496            Angle::ArcMinute => 0.0002908882086657216,
497            Angle::ArcSecond => 0.000004848136811095278,
498            Angle::Custom(value, base) => value * base.to_radians(),
499        }
500    }
501
502    pub fn to_degrees(&self) -> f64 {
503        self.to_radians() * 57.29577951308232
504    }
505}
506
507#[derive(Debug, Clone)]
508pub enum Pressure {
509    Atmospheric,
510    Bar,
511    Millibar,
512    Pascal,
513    Kilopascal,
514    Megapascal,
515    Torr,
516    MmHg,
517    Psi,
518    Custom(Force, Area),
519}
520
521impl Pressure {
522    pub fn convert_to(self, to: Self) -> Self {
523        let base_pascal = self.to_pascal();
524
525        match to {
526            Pressure::Pascal => Pressure::Pascal,
527            Pressure::Atmospheric => Pressure::Custom(
528                Force::Custom(
529                    Mass::Custom(base_pascal / 101325.0, Box::new(Mass::Kg)),
530                    Length::Meter,
531                    Time::Second,
532                ),
533                Area::SquareMeter,
534            ),
535            Pressure::Bar => Pressure::Custom(
536                Force::Custom(
537                    Mass::Custom(base_pascal / 100000.0, Box::new(Mass::Kg)),
538                    Length::Meter,
539                    Time::Second,
540                ),
541                Area::SquareMeter,
542            ),
543            Pressure::Millibar => Pressure::Custom(
544                Force::Custom(
545                    Mass::Custom(base_pascal / 100.0, Box::new(Mass::Kg)),
546                    Length::Meter,
547                    Time::Second,
548                ),
549                Area::SquareMeter,
550            ),
551            Pressure::Kilopascal => Pressure::Custom(
552                Force::Custom(
553                    Mass::Custom(base_pascal / 1000.0, Box::new(Mass::Kg)),
554                    Length::Meter,
555                    Time::Second,
556                ),
557                Area::SquareMeter,
558            ),
559            Pressure::Megapascal => Pressure::Custom(
560                Force::Custom(
561                    Mass::Custom(base_pascal / 1000000.0, Box::new(Mass::Kg)),
562                    Length::Meter,
563                    Time::Second,
564                ),
565                Area::SquareMeter,
566            ),
567            Pressure::Torr => Pressure::Custom(
568                Force::Custom(
569                    Mass::Custom(base_pascal / 133.322, Box::new(Mass::Kg)),
570                    Length::Meter,
571                    Time::Second,
572                ),
573                Area::SquareMeter,
574            ),
575            Pressure::MmHg => Pressure::Custom(
576                Force::Custom(
577                    Mass::Custom(base_pascal / 133.322, Box::new(Mass::Kg)),
578                    Length::Meter,
579                    Time::Second,
580                ),
581                Area::SquareMeter,
582            ),
583            Pressure::Psi => Pressure::Custom(
584                Force::Custom(
585                    Mass::Custom(base_pascal / 6894.757293168361, Box::new(Mass::Kg)),
586                    Length::Meter,
587                    Time::Second,
588                ),
589                Area::SquareMeter,
590            ),
591            Pressure::Custom(force, area) => {
592                let target_force = Force::Newton.convert_to(force);
593                let target_area = Area::SquareMeter.convert_to(area);
594                Pressure::Custom(target_force, target_area)
595            }
596        }
597    }
598
599    pub fn to_pascal(&self) -> f64 {
600        match self {
601            Pressure::Pascal => 1.0,
602            Pressure::Atmospheric => 101325.0,
603            Pressure::Bar => 100000.0,
604            Pressure::Millibar => 100.0,
605            Pressure::Kilopascal => 1000.0,
606            Pressure::Megapascal => 1000000.0,
607            Pressure::Torr => 133.322,
608            Pressure::MmHg => 133.322,
609            Pressure::Psi => 6894.757293168361,
610            Pressure::Custom(force, area) => {
611                let newtons = match force {
612                    Force::Newton => 1.0,
613                    Force::Dyne => 0.00001,
614                    Force::Pound => 4.448222,
615                    Force::Kg => 9.80665,
616                    Force::Custom(mass, length, time) => {
617                        let kg = mass.clone().convert_to(Mass::Kg).to_kg();
618                        let meters = length.clone().convert_to(Length::Meter).to_meters();
619                        let seconds = time.clone().convert_to(Time::Second).to_seconds();
620                        kg * (meters / (seconds * seconds))
621                    }
622                };
623
624                let square_meters = match area {
625                    Area::SquareMeter => 1.0,
626                    Area::Acre => 4046.8564224,
627                    Area::Hectare => 10000.0,
628                    Area::SquareKilometer => 1000000.0,
629                    Area::SquareMile => 2589988.110336,
630                    Area::SquareFoot => 0.09290304,
631                    Area::Custom(length) => {
632                        let meters = length.clone().convert_to(Length::Meter).to_meters();
633                        meters * meters
634                    }
635                };
636
637                newtons / square_meters
638            }
639        }
640    }
641
642    pub fn to_bar(&self) -> f64 {
643        self.to_pascal() / 100000.0
644    }
645
646    pub fn to_atm(&self) -> f64 {
647        self.to_pascal() / 101325.0
648    }
649
650    pub fn to_psi(&self) -> f64 {
651        self.to_pascal() / 6894.757293168361
652    }
653}
654
655#[derive(Debug, Clone)]
656pub enum Area {
657    Acre,
658    Hectare,
659    SquareMeter,
660    SquareKilometer,
661    SquareMile,
662    SquareFoot,
663    Custom(Length),
664}
665
666impl Area {
667    pub fn convert_to(self, to: Self) -> Self {
668        let base_square_meters = self.to_square_meters();
669
670        match to {
671            Area::SquareMeter => Area::Custom(Length::Meter),
672            Area::Acre => Area::Custom(Length::Custom(
673                (base_square_meters / 4046.8564224).sqrt(),
674                Box::new(Length::Custom(2.0, Box::new(Length::Meter))),
675            )),
676            Area::Hectare => Area::Custom(Length::Custom(
677                (base_square_meters / 10000.0).sqrt(),
678                Box::new(Length::Custom(100.0, Box::new(Length::Meter))),
679            )),
680            Area::SquareKilometer => Area::Custom(Length::Custom(
681                (base_square_meters / 1_000_000.0).sqrt(),
682                Box::new(Length::Kilometer),
683            )),
684            Area::SquareMile => Area::Custom(Length::Custom(
685                (base_square_meters / 2_589_988.110336).sqrt(),
686                Box::new(Length::Mile),
687            )),
688            Area::SquareFoot => Area::Custom(Length::Custom(
689                (base_square_meters / 0.09290304).sqrt(),
690                Box::new(Length::Foot),
691            )),
692            Area::Custom(length) => {
693                let target_length = Length::Meter.convert_to(length);
694                Area::Custom(target_length)
695            }
696        }
697    }
698
699    pub fn to_square_meters(&self) -> f64 {
700        match self {
701            Area::SquareMeter => 1.0,
702            Area::Acre => 4046.8564224,
703            Area::Hectare => 10000.0,
704            Area::SquareKilometer => 1_000_000.0,
705            Area::SquareMile => 2_589_988.110336,
706            Area::SquareFoot => 0.09290304,
707            Area::Custom(length) => {
708                let meters = length.clone().convert_to(Length::Meter).to_meters();
709                meters * meters
710            }
711        }
712    }
713
714    pub fn to_acres(&self) -> f64 {
715        self.to_square_meters() / 4046.8564224
716    }
717
718    pub fn to_hectares(&self) -> f64 {
719        self.to_square_meters() / 10000.0
720    }
721
722    pub fn to_square_kilometers(&self) -> f64 {
723        self.to_square_meters() / 1_000_000.0
724    }
725
726    pub fn to_square_miles(&self) -> f64 {
727        self.to_square_meters() / 2_589_988.110336
728    }
729
730    pub fn to_square_feet(&self) -> f64 {
731        self.to_square_meters() / 0.09290304
732    }
733}
734
735impl Length {
736    pub fn squared(&self) -> Area {
737        Area::Custom(self.clone())
738    }
739}
740
741#[derive(Debug, Clone)]
742pub enum Volume {
743    Custom(Length),
744    CubicMeter,
745    CubicFoot,
746    Liter,
747    Milliliter,
748    Gallon,
749    Barell,
750    FluidOunce,
751    Pint,
752    Quart,
753}
754
755impl Volume {
756    pub fn convert_to(self, to: Self) -> Self {
757        let base_cubic_meters = self.to_cubic_meters();
758
759        match to {
760            Volume::CubicMeter => Volume::Custom(Length::Meter),
761            Volume::CubicFoot => Volume::Custom(Length::Custom(
762                (base_cubic_meters / 0.028316846592).cbrt(),
763                Box::new(Length::Foot),
764            )),
765            Volume::Liter => Volume::Custom(Length::Custom(
766                (base_cubic_meters / 0.001).cbrt(),
767                Box::new(Length::Custom(0.1, Box::new(Length::Meter))),
768            )),
769            Volume::Milliliter => Volume::Custom(Length::Custom(
770                (base_cubic_meters / 0.000001).cbrt(),
771                Box::new(Length::Custom(0.01, Box::new(Length::Meter))),
772            )),
773            Volume::Gallon => Volume::Custom(Length::Custom(
774                (base_cubic_meters / 0.003785411784).cbrt(),
775                Box::new(Length::Custom(0.1546, Box::new(Length::Meter))),
776            )),
777            Volume::Barell => Volume::Custom(Length::Custom(
778                (base_cubic_meters / 0.158987294928).cbrt(),
779                Box::new(Length::Custom(0.5408, Box::new(Length::Meter))),
780            )),
781            Volume::FluidOunce => Volume::Custom(Length::Custom(
782                (base_cubic_meters / 0.0000295735295625).cbrt(),
783                Box::new(Length::Custom(0.0312, Box::new(Length::Meter))),
784            )),
785            Volume::Pint => Volume::Custom(Length::Custom(
786                (base_cubic_meters / 0.000473176473).cbrt(),
787                Box::new(Length::Custom(0.0781, Box::new(Length::Meter))),
788            )),
789            Volume::Quart => Volume::Custom(Length::Custom(
790                (base_cubic_meters / 0.000946352946).cbrt(),
791                Box::new(Length::Custom(0.0984, Box::new(Length::Meter))),
792            )),
793            Volume::Custom(length) => {
794                let target_length = Length::Meter.convert_to(length);
795                Volume::Custom(target_length)
796            }
797        }
798    }
799
800    pub fn to_cubic_meters(&self) -> f64 {
801        match self {
802            Volume::CubicMeter => 1.0,
803            Volume::CubicFoot => 0.028316846592,
804            Volume::Liter => 0.001,
805            Volume::Milliliter => 0.000001,
806            Volume::Gallon => 0.003785411784,
807            Volume::Barell => 0.158987294928,
808            Volume::FluidOunce => 0.0000295735295625,
809            Volume::Pint => 0.000473176473,
810            Volume::Quart => 0.000946352946,
811            Volume::Custom(length) => {
812                let meters = length.clone().convert_to(Length::Meter).to_meters();
813                meters * meters * meters
814            }
815        }
816    }
817
818    pub fn to_liters(&self) -> f64 {
819        self.to_cubic_meters() * 1000.0
820    }
821
822    pub fn to_gallons(&self) -> f64 {
823        self.to_cubic_meters() / 0.003785411784
824    }
825
826    pub fn to_cubic_feet(&self) -> f64 {
827        self.to_cubic_meters() / 0.028316846592
828    }
829
830    pub fn to_milliliters(&self) -> f64 {
831        self.to_cubic_meters() * 1_000_000.0
832    }
833
834    pub fn to_fluid_ounces(&self) -> f64 {
835        self.to_cubic_meters() / 0.0000295735295625
836    }
837
838    pub fn to_pints(&self) -> f64 {
839        self.to_cubic_meters() / 0.000473176473
840    }
841
842    pub fn to_quarts(&self) -> f64 {
843        self.to_cubic_meters() / 0.000946352946
844    }
845
846    pub fn to_barrels(&self) -> f64 {
847        self.to_cubic_meters() / 0.158987294928
848    }
849}
850
851impl Length {
852    pub fn cubed(&self) -> Volume {
853        Volume::Custom(self.clone())
854    }
855}
856
857#[derive(Debug, Clone)]
858pub enum Temperature {
859    Celsius,
860    Fahrenheit,
861    Kelvin,
862    Rankine,
863}
864
865impl Temperature {
866    pub fn convert_to(self, to: Self) -> Self {
867        match to {
868            Temperature::Kelvin => Temperature::Kelvin,
869            Temperature::Celsius => Temperature::Celsius,
870            Temperature::Fahrenheit => Temperature::Fahrenheit,
871            Temperature::Rankine => Temperature::Rankine,
872        }
873    }
874
875    pub fn to_kelvin(&self, value: f64) -> f64 {
876        match self {
877            Temperature::Kelvin => value,
878            Temperature::Celsius => value + 273.15,
879            Temperature::Fahrenheit => (value - 32.0) * 5.0 / 9.0 + 273.15,
880            Temperature::Rankine => value * 5.0 / 9.0,
881        }
882    }
883
884    pub fn from_kelvin(&self, kelvin: f64) -> f64 {
885        match self {
886            Temperature::Kelvin => kelvin,
887            Temperature::Celsius => kelvin - 273.15,
888            Temperature::Fahrenheit => (kelvin - 273.15) * 9.0 / 5.0 + 32.0,
889            Temperature::Rankine => kelvin * 9.0 / 5.0,
890        }
891    }
892
893    pub fn to_celsius(&self, value: f64) -> f64 {
894        let kelvin = self.to_kelvin(value);
895        Temperature::Celsius.from_kelvin(kelvin)
896    }
897
898    pub fn to_fahrenheit(&self, value: f64) -> f64 {
899        let kelvin = self.to_kelvin(value);
900        Temperature::Fahrenheit.from_kelvin(kelvin)
901    }
902
903    pub fn to_rankine(&self, value: f64) -> f64 {
904        let kelvin = self.to_kelvin(value);
905        Temperature::Rankine.from_kelvin(kelvin)
906    }
907}
908
909#[derive(Debug, Clone)]
910pub enum Energy {
911    Joule,
912    Kilojoule,
913    Megajoule,
914    Ev,
915    KiloEv,
916    MegaEv,
917    Calorie,
918    Kilocalorie,
919    Erg,
920    TNT,
921    // Custom energy as work
922    Custom(Force, Length),
923}
924
925impl Energy {
926    pub fn convert_to(self, to: Self) -> Self {
927        let base_joules = self.to_joules();
928
929        match to {
930            Energy::Joule => Energy::Joule,
931            Energy::Kilojoule => Energy::Custom(
932                Force::Custom(
933                    Mass::Custom(base_joules / 1000.0, Box::new(Mass::Kg)),
934                    Length::Meter,
935                    Time::Second,
936                ),
937                Length::Meter,
938            ),
939            Energy::Megajoule => Energy::Custom(
940                Force::Custom(
941                    Mass::Custom(base_joules / 1_000_000.0, Box::new(Mass::Kg)),
942                    Length::Meter,
943                    Time::Second,
944                ),
945                Length::Meter,
946            ),
947            Energy::Ev => Energy::Custom(
948                Force::Custom(
949                    Mass::Custom(base_joules / 1.602176634e-19, Box::new(Mass::Kg)),
950                    Length::Meter,
951                    Time::Second,
952                ),
953                Length::Meter,
954            ),
955            Energy::KiloEv => Energy::Custom(
956                Force::Custom(
957                    Mass::Custom(base_joules / 1.602176634e-16, Box::new(Mass::Kg)),
958                    Length::Meter,
959                    Time::Second,
960                ),
961                Length::Meter,
962            ),
963            Energy::MegaEv => Energy::Custom(
964                Force::Custom(
965                    Mass::Custom(base_joules / 1.602176634e-13, Box::new(Mass::Kg)),
966                    Length::Meter,
967                    Time::Second,
968                ),
969                Length::Meter,
970            ),
971            Energy::Calorie => Energy::Custom(
972                Force::Custom(
973                    Mass::Custom(base_joules / 4.184, Box::new(Mass::Kg)),
974                    Length::Meter,
975                    Time::Second,
976                ),
977                Length::Meter,
978            ),
979            Energy::Kilocalorie => Energy::Custom(
980                Force::Custom(
981                    Mass::Custom(base_joules / 4184.0, Box::new(Mass::Kg)),
982                    Length::Meter,
983                    Time::Second,
984                ),
985                Length::Meter,
986            ),
987            Energy::Erg => Energy::Custom(
988                Force::Custom(
989                    Mass::Custom(base_joules / 1e-7, Box::new(Mass::Kg)),
990                    Length::Meter,
991                    Time::Second,
992                ),
993                Length::Meter,
994            ),
995            Energy::TNT => Energy::Custom(
996                Force::Custom(
997                    Mass::Custom(base_joules / 4.184e9, Box::new(Mass::Kg)),
998                    Length::Meter,
999                    Time::Second,
1000                ),
1001                Length::Meter,
1002            ),
1003            Energy::Custom(force, length) => {
1004                let target_force = Force::Newton.convert_to(force);
1005                let target_length = Length::Meter.convert_to(length);
1006                Energy::Custom(target_force, target_length)
1007            }
1008        }
1009    }
1010
1011    pub fn to_joules(&self) -> f64 {
1012        match self {
1013            Energy::Joule => 1.0,
1014            Energy::Kilojoule => 1000.0,
1015            Energy::Megajoule => 1_000_000.0,
1016            Energy::Ev => 1.602176634e-19,
1017            Energy::KiloEv => 1.602176634e-16,
1018            Energy::MegaEv => 1.602176634e-13,
1019            Energy::Calorie => 4.184,
1020            Energy::Kilocalorie => 4184.0,
1021            Energy::Erg => 1e-7,
1022            Energy::TNT => 4.184e9,
1023            Energy::Custom(force, length) => {
1024                let newtons = match force {
1025                    Force::Newton => 1.0,
1026                    Force::Dyne => 1e-5,
1027                    Force::Pound => 4.448222,
1028                    Force::Kg => 9.80665,
1029                    Force::Custom(mass, len, time) => {
1030                        let kg = mass.clone().convert_to(Mass::Kg).to_kg();
1031                        let m = len.clone().convert_to(Length::Meter).to_meters();
1032                        let s = time.clone().convert_to(Time::Second).to_seconds();
1033                        kg * (m / (s * s))
1034                    }
1035                };
1036                let meters = length.clone().convert_to(Length::Meter).to_meters();
1037                newtons * meters
1038            }
1039        }
1040    }
1041
1042    pub fn to_calories(&self) -> f64 {
1043        self.to_joules() / 4.184
1044    }
1045
1046    pub fn to_kilocalories(&self) -> f64 {
1047        self.to_joules() / 4184.0
1048    }
1049
1050    pub fn to_electron_volts(&self) -> f64 {
1051        self.to_joules() / 1.602176634e-19
1052    }
1053
1054    pub fn to_tnt_equivalent(&self) -> f64 {
1055        self.to_joules() / 4.184e9
1056    }
1057}
1058
1059#[derive(Debug, Clone)]
1060pub enum Power {
1061    Watt,
1062    Kilowatt,
1063    Megawatt,
1064    Hp,
1065    // Custom power as energy per time
1066    Custom(Energy, Time),
1067}
1068
1069impl Power {
1070    pub fn convert_to(self, to: Self) -> Self {
1071        let base_watts = self.to_watts();
1072
1073        match to {
1074            Power::Watt => Power::Watt,
1075            Power::Kilowatt => Power::Custom(
1076                Energy::Joule,
1077                Time::Custom(base_watts / 1000.0, Box::new(Time::Second)),
1078            ),
1079            Power::Megawatt => Power::Custom(
1080                Energy::Joule,
1081                Time::Custom(base_watts / 1_000_000.0, Box::new(Time::Second)),
1082            ),
1083            Power::Hp => Power::Custom(
1084                Energy::Joule,
1085                Time::Custom(base_watts / 745.7, Box::new(Time::Second)),
1086            ),
1087            Power::Custom(energy, time) => {
1088                let target_energy = Energy::Joule.convert_to(energy);
1089                let target_time = Time::Second.convert_to(time);
1090                Power::Custom(target_energy, target_time)
1091            }
1092        }
1093    }
1094
1095    pub fn to_watts(&self) -> f64 {
1096        match self {
1097            Power::Watt => 1.0,
1098            Power::Kilowatt => 1000.0,
1099            Power::Megawatt => 1_000_000.0,
1100            Power::Hp => 745.7,
1101            Power::Custom(energy, time) => {
1102                let joules = energy.to_joules();
1103                let seconds = time.to_seconds();
1104                joules / seconds
1105            }
1106        }
1107    }
1108
1109    pub fn to_kilowatts(&self) -> f64 {
1110        self.to_watts() / 1000.0
1111    }
1112
1113    pub fn to_megawatts(&self) -> f64 {
1114        self.to_watts() / 1_000_000.0
1115    }
1116
1117    pub fn to_horsepower(&self) -> f64 {
1118        self.to_watts() / 745.7
1119    }
1120}
1121
1122#[derive(Debug, Clone)]
1123pub enum Force {
1124    Newton,
1125    Dyne,
1126    Pound,
1127    Kg,
1128    // Custom force as mass times acceleration
1129    Custom(Mass, Length, Time),
1130}
1131
1132impl Force {
1133    pub fn convert_to(self, to: Self) -> Self {
1134        let base_newtons = self.to_newtons();
1135
1136        match to {
1137            Force::Newton => Force::Newton,
1138            Force::Dyne => Force::Custom(
1139                Mass::Custom(base_newtons / 1e-5, Box::new(Mass::Gram)),
1140                Length::Centimeter,
1141                Time::Second,
1142            ),
1143            Force::Pound => Force::Custom(
1144                Mass::Custom(base_newtons / 4.448222, Box::new(Mass::Pound)),
1145                Length::Meter,
1146                Time::Second,
1147            ),
1148            Force::Kg => Force::Custom(
1149                Mass::Custom(base_newtons / 9.80665, Box::new(Mass::Kg)),
1150                Length::Meter,
1151                Time::Second,
1152            ),
1153            Force::Custom(mass, length, time) => {
1154                let target_mass = Mass::Kg.convert_to(mass);
1155                let target_length = Length::Meter.convert_to(length);
1156                let target_time = Time::Second.convert_to(time);
1157                Force::Custom(target_mass, target_length, target_time)
1158            }
1159        }
1160    }
1161
1162    pub fn to_newtons(&self) -> f64 {
1163        match self {
1164            Force::Newton => 1.0,
1165            Force::Dyne => 1e-5,
1166            Force::Pound => 4.448222,
1167            Force::Kg => 9.80665,
1168            Force::Custom(mass, length, time) => {
1169                let kg = mass.clone().convert_to(Mass::Kg).to_kg();
1170                let meters = length.clone().convert_to(Length::Meter).to_meters();
1171                let seconds = time.clone().convert_to(Time::Second).to_seconds();
1172                kg * (meters / (seconds * seconds))
1173            }
1174        }
1175    }
1176
1177    pub fn to_pounds(&self) -> f64 {
1178        self.to_newtons() / 4.448222
1179    }
1180
1181    pub fn to_dynes(&self) -> f64 {
1182        self.to_newtons() * 100000.0
1183    }
1184
1185    pub fn to_kilograms_force(&self) -> f64 {
1186        self.to_newtons() / 9.80665
1187    }
1188}
1189
1190impl Mass {
1191    pub fn times_acceleration(&self, length: Length, time: Time) -> Force {
1192        Force::Custom(self.clone(), length, time)
1193    }
1194}
1195
1196impl Energy {
1197    pub fn per_time(&self, time: Time) -> Power {
1198        Power::Custom(self.clone(), time)
1199    }
1200}
1201
1202#[derive(Debug, Clone)]
1203pub enum ElectricCharge {
1204    Coulomb,
1205    ElementaryCharge,
1206    // Custom charge as current times time
1207    Custom(Box<Current>, Time),
1208}
1209
1210impl ElectricCharge {
1211    pub fn convert_to(self, to: Self) -> Self {
1212        let base_coulombs = self.to_coulombs();
1213
1214        match to {
1215            ElectricCharge::Coulomb => ElectricCharge::Coulomb,
1216            ElectricCharge::ElementaryCharge => ElectricCharge::Custom(
1217                Box::new(Current::Custom(
1218                    ElectricCharge::Coulomb,
1219                    Time::Custom(base_coulombs / 1.602176634e-19, Box::new(Time::Second)),
1220                )),
1221                Time::Second,
1222            ),
1223            ElectricCharge::Custom(current, time) => {
1224                let target_current = Current::Ampere.convert_to(*current);
1225                let target_time = Time::Second.convert_to(time);
1226                ElectricCharge::Custom(Box::new(target_current), target_time)
1227            }
1228        }
1229    }
1230
1231    pub fn to_coulombs(&self) -> f64 {
1232        match self {
1233            ElectricCharge::Coulomb => 1.0,
1234            ElectricCharge::ElementaryCharge => 1.602176634e-19,
1235            ElectricCharge::Custom(current, time) => {
1236                let amperes = match **current {
1237                    Current::Ampere => 1.0,
1238                    Current::Milliampere => 0.001,
1239                    Current::Custom(ref charge, ref t) => {
1240                        charge
1241                            .clone()
1242                            .convert_to(ElectricCharge::Coulomb)
1243                            .to_coulombs()
1244                            / t.clone().convert_to(Time::Second).to_seconds()
1245                    }
1246                };
1247                let seconds = time.to_seconds();
1248                amperes * seconds
1249            }
1250        }
1251    }
1252
1253    pub fn to_elementary_charges(&self) -> f64 {
1254        self.to_coulombs() / 1.602176634e-19
1255    }
1256}
1257
1258#[derive(Debug, Clone)]
1259pub enum Current {
1260    Ampere,
1261    Milliampere,
1262    Custom(ElectricCharge, Time),
1263}
1264
1265impl Current {
1266    pub fn convert_to(self, to: Self) -> Self {
1267        let base_amperes = self.to_amperes();
1268
1269        match to {
1270            Current::Ampere => Current::Ampere,
1271            Current::Milliampere => Current::Custom(
1272                ElectricCharge::Coulomb,
1273                Time::Custom(base_amperes / 0.001, Box::new(Time::Second)),
1274            ),
1275            Current::Custom(charge, time) => {
1276                let target_charge = ElectricCharge::Coulomb.convert_to(charge);
1277                let target_time = Time::Second.convert_to(time);
1278                Current::Custom(target_charge, target_time)
1279            }
1280        }
1281    }
1282
1283    pub fn to_amperes(&self) -> f64 {
1284        match self {
1285            Current::Ampere => 1.0,
1286            Current::Milliampere => 0.001,
1287            Current::Custom(charge, time) => {
1288                let coulombs = charge.to_coulombs();
1289                let seconds = time.to_seconds();
1290                coulombs / seconds
1291            }
1292        }
1293    }
1294
1295    pub fn to_milliamperes(&self) -> f64 {
1296        self.to_amperes() * 1000.0
1297    }
1298}
1299
1300#[derive(Debug, Clone)]
1301pub enum Frequency {
1302    Hertz,
1303    Kilohertz,
1304    Megahertz,
1305    Gigahertz,
1306    // Custom frequency as 1/time
1307    Custom(Time),
1308}
1309
1310impl Frequency {
1311    pub fn convert_to(self, to: Self) -> Self {
1312        let base_hertz = self.to_hertz();
1313
1314        match to {
1315            Frequency::Hertz => Frequency::Hertz,
1316            Frequency::Kilohertz => {
1317                Frequency::Custom(Time::Custom(base_hertz / 1000.0, Box::new(Time::Second)))
1318            }
1319            Frequency::Megahertz => Frequency::Custom(Time::Custom(
1320                base_hertz / 1_000_000.0,
1321                Box::new(Time::Second),
1322            )),
1323            Frequency::Gigahertz => Frequency::Custom(Time::Custom(
1324                base_hertz / 1_000_000_000.0,
1325                Box::new(Time::Second),
1326            )),
1327            Frequency::Custom(time) => {
1328                let target_time = Time::Second.convert_to(time);
1329                Frequency::Custom(target_time)
1330            }
1331        }
1332    }
1333
1334    pub fn to_hertz(&self) -> f64 {
1335        match self {
1336            Frequency::Hertz => 1.0,
1337            Frequency::Kilohertz => 1000.0,
1338            Frequency::Megahertz => 1_000_000.0,
1339            Frequency::Gigahertz => 1_000_000_000.0,
1340            Frequency::Custom(time) => 1.0 / time.to_seconds(),
1341        }
1342    }
1343
1344    pub fn to_kilohertz(&self) -> f64 {
1345        self.to_hertz() / 1000.0
1346    }
1347
1348    pub fn to_megahertz(&self) -> f64 {
1349        self.to_hertz() / 1_000_000.0
1350    }
1351
1352    pub fn to_gigahertz(&self) -> f64 {
1353        self.to_hertz() / 1_000_000_000.0
1354    }
1355}
1356
1357#[derive(Debug, Clone)]
1358pub enum Acceleration {
1359    MetersPerSecondSquared,
1360    G, // Earth's gravitational acceleration
1361    // Custom acceleration
1362    Custom(Length, Time, Time),
1363}
1364
1365impl Acceleration {
1366    pub fn convert_to(self, to: Self) -> Self {
1367        // Convert to meters per second squared as base unit
1368        let base_mps2 = self.to_mps2();
1369
1370        match to {
1371            Acceleration::MetersPerSecondSquared => Acceleration::MetersPerSecondSquared,
1372            Acceleration::G => Acceleration::Custom(
1373                Length::Custom(base_mps2 / 9.80665, Box::new(Length::Meter)),
1374                Time::Second,
1375                Time::Second,
1376            ),
1377            Acceleration::Custom(length, time1, time2) => {
1378                let target_length = Length::Meter.convert_to(length);
1379                let target_time1 = Time::Second.convert_to(time1);
1380                let target_time2 = Time::Second.convert_to(time2);
1381                Acceleration::Custom(target_length, target_time1, target_time2)
1382            }
1383        }
1384    }
1385
1386    pub fn to_mps2(&self) -> f64 {
1387        match self {
1388            Acceleration::MetersPerSecondSquared => 1.0,
1389            Acceleration::G => 9.80665,
1390            Acceleration::Custom(length, time1, time2) => {
1391                let meters = length.clone().convert_to(Length::Meter).to_meters();
1392                let seconds1 = time1.clone().convert_to(Time::Second).to_seconds();
1393                let seconds2 = time2.clone().convert_to(Time::Second).to_seconds();
1394                meters / (seconds1 * seconds2)
1395            }
1396        }
1397    }
1398
1399    pub fn to_g(&self) -> f64 {
1400        self.to_mps2() / 9.80665
1401    }
1402}
1403
1404impl Time {
1405    pub fn frequency(&self) -> Frequency {
1406        Frequency::Custom(self.clone())
1407    }
1408}
1409
1410impl Length {
1411    pub fn per_time_squared(&self, time1: Time, time2: Time) -> Acceleration {
1412        Acceleration::Custom(self.clone(), time1, time2)
1413    }
1414}