1use crate::calc::meaning::AreaKind::*;
2use crate::calc::meaning::DataKind::*;
3use crate::calc::meaning::DeltaKind::*;
4use crate::calc::meaning::LengthKind::*;
5use crate::calc::meaning::MassKind::*;
6use crate::calc::meaning::Meaning::*;
7use crate::calc::meaning::PrefixKind::*;
8use crate::calc::meaning::SpeedKind::*;
9use crate::calc::meaning::TempKind::*;
10use crate::calc::meaning::VolumeKind::*;
11use crate::core::interface::Meanings;
12use crate::error::{EngineError, MyResult};
13use crate::util::number::create_ratio;
14use num::{BigRational, CheckedAdd, CheckedDiv, CheckedMul, CheckedSub, One, Zero};
15use std::borrow::Cow;
16use std::cell::RefCell;
17use std::fmt::{Display, Formatter};
18use std::ops::{DerefMut, Div, Mul};
19
20#[macro_export]
21macro_rules! combine_inner {
22 ($lhs:expr, $rhs:expr) => {
23 None
24 };
25 ($lhs:expr, $rhs:expr, $head:ident) => {
26 Meaning::$head($lhs, $rhs)
27 };
28 ($lhs:expr, $rhs:expr, $head:ident, $($tail:ident),+) => {
29 Meaning::$head($lhs, $rhs).or_else(|| combine_inner!($lhs, $rhs, $($tail),*))
30 };
31}
32
33#[macro_export]
34macro_rules! combine_cast {
35 ($input:expr, $output:expr, $($tail:ident),+ $(,)?) => {
36 {
37 let input = $input;
38 let output = $output;
39 let result = combine_inner!(input, output, $($tail),*);
40 result.ok_or_else(|| MyError::Engine(EngineError::BadCastOp(input, output)))
41 }
42 };
43}
44
45#[macro_export]
46macro_rules! combine_binary {
47 ($lhs:expr, $rhs:expr, $($tail:ident),+ $(,)?) => {
48 {
49 let lhs = $lhs;
50 let rhs = $rhs;
51 let result = combine_inner!(lhs, rhs, $($tail),*);
52 result.ok_or_else(|| MyError::Engine(EngineError::BadCastOp(rhs, lhs)))
53 }
54 };
55}
56
57pub trait UnitInfo {
61 fn walk_values<F: FnMut(Self) -> MyResult<()>>(
62 multiply: bool,
63 divide: bool,
64 function: F,
65 ) -> MyResult<()> where Self: Sized;
66
67 fn get_factor(&self) -> BigRational {
68 BigRational::one()
69 }
70
71 fn get_offset(&self) -> BigRational {
72 BigRational::zero()
73 }
74
75 fn get_name(&self) -> Option<String>;
76
77 fn get_symbol(&self) -> Option<String>;
78}
79
80#[derive(Clone, Copy, Debug, PartialEq)]
81pub enum PrefixKind {
82 Quetta,
83 Ronna,
84 Yotta,
85 Zetta,
86 Exa,
87 Peta,
88 Tera,
89 Giga,
90 Mega,
91 Kilo,
92 Hecto,
93 Deca,
94 Unit,
95 Deci,
96 Centi,
97 Milli,
98 Micro,
99 Nano,
100 Pico,
101 Femto,
102 Atto,
103 Zepto,
104 Yocto,
105 Ronto,
106 Quecto,
107}
108
109#[derive(Clone, Copy, Debug, PartialEq)]
110pub enum DeltaKind {
111 Second(PrefixKind),
112 Minute,
113 Hour,
114 Day,
115 Week,
116 Month,
117 Year,
118 HMS,
119}
120
121#[derive(Clone, Copy, Debug, PartialEq)]
122pub enum LengthKind {
123 Metre(PrefixKind),
124 Inch,
125 Foot,
126 Yard,
127 Mile,
128}
129
130#[derive(Clone, Copy, Debug, PartialEq)]
131pub enum AreaKind {
132 Square(LengthKind),
133 Hectare,
134 Acre,
135}
136
137#[derive(Clone, Copy, Debug, PartialEq)]
138pub enum VolumeKind {
139 Cubic(LengthKind),
140 Litre(PrefixKind),
141 Tsp,
142 Tbsp,
143 Floz,
144 Pint,
145 Quart,
146 Gallon,
147 Barrel,
148 USTsp,
149 USTbsp,
150 USFloz,
151 USCup,
152 USPint,
153 USQuart,
154 USGallon,
155 USBarrel,
156}
157
158#[derive(Clone, Copy, Debug, PartialEq)]
159pub enum SpeedKind {
160 Ratio(LengthKind, DeltaKind),
161 Mach,
162 Light,
163}
164
165#[derive(Clone, Copy, Debug, PartialEq)]
166pub enum MassKind {
167 Gram(PrefixKind),
168 Ounce,
169 Pound,
170 Stone,
171 Ton,
172}
173
174#[derive(Clone, Copy, Debug, PartialEq)]
175pub enum TempKind {
176 Kelvin(PrefixKind),
177 Celsius,
178 Fahrenheit,
179 Rankine,
180}
181
182#[derive(Clone, Copy, Debug, PartialEq)]
183pub enum DataKind {
184 Byte(PrefixKind),
185 Bit,
186}
187
188#[derive(Clone, Copy, Debug, PartialEq)]
189pub enum Meaning {
190 Plain,
191 Delta(DeltaKind),
192 Time,
193 Length(LengthKind),
194 Area(AreaKind),
195 Volume(VolumeKind),
196 Speed(SpeedKind),
197 Mass(MassKind),
198 Temp(TempKind),
199 Data(DataKind),
200}
201
202impl PrefixKind {
203 pub fn walk_values<F: FnMut(Self) -> MyResult<()>>(
204 multiply: bool,
205 divide: bool,
206 mut function: F,
207 ) -> MyResult<()> {
208 if multiply {
209 function(Quetta)?;
210 function(Ronna)?;
211 function(Yotta)?;
212 function(Zetta)?;
213 function(Exa)?;
214 function(Peta)?;
215 function(Tera)?;
216 function(Giga)?;
217 function(Mega)?;
218 function(Kilo)?;
219 function(Hecto)?;
220 function(Deca)?;
221 }
222 function(Unit)?;
223 if divide {
224 function(Deci)?;
225 function(Centi)?;
226 function(Milli)?;
227 function(Micro)?;
228 function(Nano)?;
229 function(Pico)?;
230 function(Femto)?;
231 function(Atto)?;
232 function(Zepto)?;
233 function(Yocto)?;
234 function(Ronto)?;
235 function(Quecto)?;
236 }
237 Ok(())
238 }
239}
240
241impl PrefixKind {
242 fn get_factor(&self) -> BigRational {
243 let power = self.get_power();
244 create_ratio(10, 1).pow(power)
245 }
246
247 pub fn get_power(&self) -> i32 {
248 match self {
249 Quetta => 30,
250 Ronna => 27,
251 Yotta => 24,
252 Zetta => 21,
253 Exa => 18,
254 Peta => 15,
255 Tera => 12,
256 Giga => 9,
257 Mega => 6,
258 Kilo => 3,
259 Hecto => 2,
260 Deca => 1,
261 Unit => 0,
262 Deci => -1,
263 Centi => -2,
264 Milli => -3,
265 Micro => -6,
266 Nano => -9,
267 Pico => -12,
268 Femto => -15,
269 Atto => -18,
270 Zepto => -21,
271 Yocto => -24,
272 Ronto => -27,
273 Quecto => -30,
274 }
275 }
276
277 pub fn get_name(&self) -> &'static str {
278 match self {
279 Quetta => "quetta",
280 Ronna => "ronna",
281 Yotta => "yotta",
282 Zetta => "zetta",
283 Exa => "exa",
284 Peta => "peta",
285 Tera => "tera",
286 Giga => "giga",
287 Mega => "mega",
288 Kilo => "kilo",
289 Hecto => "hecto",
290 Deca => "deca",
291 Unit => "",
292 Deci => "deci",
293 Centi => "centi",
294 Milli => "milli",
295 Micro => "micro",
296 Nano => "nano",
297 Pico => "pico",
298 Femto => "femto",
299 Atto => "atto",
300 Zepto => "zepto",
301 Yocto => "yocto",
302 Ronto => "ronto",
303 Quecto => "quecto",
304 }
305 }
306
307 pub fn get_symbol(&self) -> &'static str {
308 match self {
309 Quetta => "Q",
310 Ronna => "R",
311 Yotta => "Y",
312 Zetta => "Z",
313 Exa => "E",
314 Peta => "P",
315 Tera => "T",
316 Giga => "G",
317 Mega => "M",
318 Kilo => "k",
319 Hecto => "h",
320 Deca => "da",
321 Unit => "",
322 Deci => "d",
323 Centi => "c",
324 Milli => "m",
325 Micro => "u",
326 Nano => "n",
327 Pico => "p",
328 Femto => "f",
329 Atto => "a",
330 Zepto => "z",
331 Yocto => "y",
332 Ronto => "r",
333 Quecto => "q",
334 }
335 }
336}
337
338impl UnitInfo for DeltaKind {
339 fn walk_values<F: FnMut(Self) -> MyResult<()>>(
340 multiply: bool,
341 divide: bool,
342 mut function: F,
343 ) -> MyResult<()> {
344 PrefixKind::walk_values(multiply, divide, |prefix| function(Second(prefix)))?;
345 function(Minute)?;
346 function(Hour)?;
347 function(Day)?;
348 function(Week)?;
349 function(Month)?;
350 function(Year)?;
351 function(HMS)?;
352 Ok(())
353 }
354
355 fn get_factor(&self) -> BigRational {
356 match self {
357 Second(prefix) => prefix.get_factor(),
358 Minute => create_ratio(60, 1), Hour => create_ratio(3600, 1), Day => create_ratio(86400, 1), Week => create_ratio(604800, 1), Month => create_ratio(2592000, 1), Year => create_ratio(31557600, 1), HMS => create_ratio(1, 1),
365 }
366 }
367
368 fn get_name(&self) -> Option<String> {
369 match self {
370 Second(prefix) => Some(format!("{}second", prefix.get_name())),
371 Minute => Some(String::from("minute")),
372 Hour => Some(String::from("hour")),
373 Day => Some(String::from("day")),
374 Week => Some(String::from("week")),
375 Month => Some(String::from("month")),
376 Year => Some(String::from("year")),
377 HMS => None,
378 }
379 }
380
381 fn get_symbol(&self) -> Option<String> {
382 match self {
383 Second(prefix) => Some(format!("{}s", prefix.get_symbol())),
384 _ => None,
385 }
386 }
387}
388
389impl UnitInfo for LengthKind {
390 fn walk_values<F: FnMut(Self) -> MyResult<()>>(
391 multiply: bool,
392 divide: bool,
393 mut function: F,
394 ) -> MyResult<()> {
395 PrefixKind::walk_values(multiply, divide, |prefix| function(Metre(prefix)))?;
396 function(Inch)?;
397 function(Foot)?;
398 function(Yard)?;
399 function(Mile)?;
400 Ok(())
401 }
402
403 fn get_factor(&self) -> BigRational {
404 match self {
405 Metre(prefix) => prefix.get_factor(),
406 Inch => create_ratio(254, 10000), Foot => create_ratio(3048, 10000), Yard => create_ratio(9144, 10000), Mile => create_ratio(16093440, 10000), }
411 }
412
413 fn get_name(&self) -> Option<String> {
414 match self {
415 Metre(prefix) => Some(format!("{}metre", prefix.get_name())),
416 Inch => Some(String::from("inch")),
417 Foot => Some(String::from("foot")),
418 Yard => Some(String::from("yard")),
419 Mile => Some(String::from("mile")),
420 }
421 }
422
423 fn get_symbol(&self) -> Option<String> {
424 match self {
425 Metre(prefix) => Some(format!("{}m", prefix.get_symbol())),
426 _ => None,
427 }
428 }
429}
430
431impl UnitInfo for AreaKind {
432 fn walk_values<F: FnMut(Self) -> MyResult<()>>(
433 multiply: bool,
434 divide: bool,
435 mut function: F,
436 ) -> MyResult<()> {
437 LengthKind::walk_values(multiply, divide, |length| function(Square(length)))?;
438 function(Hectare)?;
439 function(Acre)?;
440 Ok(())
441 }
442
443 fn get_factor(&self) -> BigRational {
444 match self {
445 Square(length) => length.get_factor().pow(2),
446 Hectare => create_ratio(10000, 1),
447 Acre => create_ratio(40468564224, 10000000), }
449 }
450
451 fn get_name(&self) -> Option<String> {
452 match self {
453 Square(length) => length.get_name().map(|x| format!("square-{}", x)),
454 Hectare => Some(String::from("hectare")),
455 Acre => Some(String::from("acre")),
456 }
457 }
458
459 fn get_symbol(&self) -> Option<String> {
460 match self {
461 Square(length) => length.get_symbol()
462 .or_else(|| length.get_name())
463 .map(|x| format!("{}^2", x)),
464 _ => None,
465 }
466 }
467}
468
469impl UnitInfo for VolumeKind {
470 fn walk_values<F: FnMut(Self) -> MyResult<()>>(
471 multiply: bool,
472 divide: bool,
473 mut function: F,
474 ) -> MyResult<()> {
475 LengthKind::walk_values(multiply, divide, |length| function(Cubic(length)))?;
476 PrefixKind::walk_values(multiply, divide, |prefix| function(Litre(prefix)))?;
477 function(Tsp)?;
478 function(Tbsp)?;
479 function(Floz)?;
480 function(Pint)?;
481 function(Quart)?;
482 function(Gallon)?;
483 function(Barrel)?;
484 function(USTsp)?;
485 function(USTbsp)?;
486 function(USFloz)?;
487 function(USCup)?;
488 function(USPint)?;
489 function(USQuart)?;
490 function(USGallon)?;
491 function(USBarrel)?;
492 Ok(())
493 }
494
495 fn get_factor(&self) -> BigRational {
496 match self {
497 Cubic(length) => length.get_factor().pow(3),
498 Litre(prefix) => prefix.get_factor().mul(create_ratio(1, 1000)),
499 Tsp => create_ratio(5_919_388_020_830, 1_000_000_000_000_000_000), Tbsp => create_ratio(17_758_164_062_500, 1_000_000_000_000_000_000), Floz => create_ratio(28_413_062_500_000, 1_000_000_000_000_000_000), Pint => create_ratio(568_261_250_000_000, 1_000_000_000_000_000_000), Quart => create_ratio(1_136_522_500_000_000, 1_000_000_000_000_000_000), Gallon => create_ratio(4_546_090_000_000_000, 1_000_000_000_000_000_000), Barrel => create_ratio(163_659_240_000_000_000, 1_000_000_000_000_000_000), USTsp => create_ratio(4_928_921_593_750, 1_000_000_000_000_000_000), USTbsp => create_ratio(14_786_764_781_250, 1_000_000_000_000_000_000), USFloz => create_ratio(29_573_529_562_500, 1_000_000_000_000_000_000), USCup => create_ratio(236_588_236_500_000, 1_000_000_000_000_000_000), USPint => create_ratio(473_176_473_000_000, 1_000_000_000_000_000_000), USQuart => create_ratio(946_352_946_000_000, 1_000_000_000_000_000_000), USGallon => create_ratio(3_785_411_784_000_000, 1_000_000_000_000_000_000), USBarrel => create_ratio(119_240_471_196_000_000, 1_000_000_000_000_000_000), }
515 }
516
517 fn get_name(&self) -> Option<String> {
518 match self {
519 Cubic(length) => length.get_name().map(|x| format!("cubic-{}", x)),
520 Litre(prefix) => Some(format!("{}litre", prefix.get_name())),
521 Tsp => Some(String::from("tsp")),
522 Tbsp => Some(String::from("tbsp")),
523 Floz => Some(String::from("floz")),
524 Pint => Some(String::from("pint")),
525 Quart => Some(String::from("quart")),
526 Gallon => Some(String::from("gallon")),
527 Barrel => Some(String::from("barrel")),
528 USTsp => Some(String::from("ustsp")),
529 USTbsp => Some(String::from("ustbsp")),
530 USFloz => Some(String::from("usfloz")),
531 USCup => Some(String::from("uscup")),
532 USPint => Some(String::from("uspint")),
533 USQuart => Some(String::from("usquart")),
534 USGallon => Some(String::from("usgallon")),
535 USBarrel => Some(String::from("usbarrel")),
536 }
537 }
538
539 fn get_symbol(&self) -> Option<String> {
540 match self {
541 Cubic(length) => length.get_symbol()
542 .or_else(|| length.get_name())
543 .map(|x| format!("{}^3", x)),
544 Litre(prefix) => Some(format!("{}l", prefix.get_symbol())),
545 _ => None,
546 }
547 }
548}
549
550impl UnitInfo for SpeedKind {
551 fn walk_values<F: FnMut(Self) -> MyResult<()>>(
552 multiply: bool,
553 divide: bool,
554 mut function: F,
555 ) -> MyResult<()> {
556 LengthKind::walk_values(multiply, divide, |length| {
557 DeltaKind::walk_values(false, false, |delta| function(Ratio(length, delta)))
558 })?;
559 function(Mach)?;
560 function(Light)?;
561 Ok(())
562 }
563
564 fn get_factor(&self) -> BigRational {
565 match self {
566 Ratio(length, delta) => length.get_factor().div(delta.get_factor()),
567 Mach => create_ratio(340, 1), Light => create_ratio(299792458, 1), }
570 }
571
572 fn get_name(&self) -> Option<String> {
573 match self {
574 Ratio(length, delta) => format_speed_name(*length, *delta),
575 Mach => Some(String::from("mach")),
576 Light => Some(String::from("light")),
577 }
578 }
579
580 fn get_symbol(&self) -> Option<String> {
581 match self {
582 Ratio(length, delta) => format_speed_symbol(*length, *delta),
583 _ => None,
584 }
585 }
586}
587
588fn format_speed_name(length: LengthKind, delta: DeltaKind) -> Option<String> {
589 if let Some(length) = length.get_name() {
590 if let Some(delta) = delta.get_name() {
591 return Some(format!("{}/{}", length, delta));
592 }
593 }
594 None
595}
596
597fn format_speed_symbol(length: LengthKind, delta: DeltaKind) -> Option<String> {
598 if let Some(length) = length.get_symbol().or_else(|| length.get_name()) {
599 if let Some(delta) = delta.get_symbol().or_else(|| delta.get_name()) {
600 return Some(format!("{}/{}", length, delta));
601 }
602 }
603 None
604}
605
606impl UnitInfo for MassKind {
607 fn walk_values<F: FnMut(Self) -> MyResult<()>>(
608 multiply: bool,
609 divide: bool,
610 mut function: F,
611 ) -> MyResult<()> {
612 PrefixKind::walk_values(multiply, divide, |prefix| function(Gram(prefix)))?;
613 function(Ounce)?;
614 function(Pound)?;
615 function(Stone)?;
616 function(Ton)?;
617 Ok(())
618 }
619
620 fn get_factor(&self) -> BigRational {
621 match self {
622 Gram(prefix) => prefix.get_factor(),
623 Ounce => create_ratio(28_349_523_125, 1_000_000_000), Pound => create_ratio(453_592_370_000, 1_000_000_000), Stone => create_ratio(6_350_293_180_000, 1_000_000_000), Ton => create_ratio(1_016_046_908_800_000, 1_000_000_000), }
628 }
629
630 fn get_name(&self) -> Option<String> {
631 match self {
632 Gram(prefix) => Some(format!("{}gram", prefix.get_name())),
633 Ounce => Some(String::from("ounce")),
634 Pound => Some(String::from("pound")),
635 Stone => Some(String::from("stone")),
636 Ton => Some(String::from("ton")),
637 }
638 }
639
640 fn get_symbol(&self) -> Option<String> {
641 match self {
642 Gram(prefix) => Some(format!("{}g", prefix.get_symbol())),
643 _ => None,
644 }
645 }
646}
647
648impl UnitInfo for TempKind {
649 fn walk_values<F: FnMut(Self) -> MyResult<()>>(
650 multiply: bool,
651 divide: bool,
652 mut function: F,
653 ) -> MyResult<()> {
654 PrefixKind::walk_values(multiply, divide, |prefix| function(Kelvin(prefix)))?;
655 function(Celsius)?;
656 function(Fahrenheit)?;
657 function(Rankine)?;
658 Ok(())
659 }
660
661 fn get_factor(&self) -> BigRational {
662 match self {
663 Kelvin(_) => create_ratio(1, 1),
664 Celsius => create_ratio(1, 1),
665 Fahrenheit => create_ratio(5, 9),
666 Rankine => create_ratio(5, 9),
667 }
668 }
669
670 fn get_offset(&self) -> BigRational {
671 match self {
672 Kelvin(_) => create_ratio(0, 1),
673 Celsius => create_ratio(27315, 100), Fahrenheit => create_ratio(229835, 900), Rankine => create_ratio(0, 1),
676 }
677 }
678
679 fn get_name(&self) -> Option<String> {
680 match self {
681 Kelvin(prefix) => Some(format!("{}kelvin", prefix.get_name())),
682 Celsius => Some(String::from("celsius")),
683 Fahrenheit => Some(String::from("fahrenheit")),
684 Rankine => Some(String::from("rankine")),
685 }
686 }
687
688 fn get_symbol(&self) -> Option<String> {
689 match self {
690 Kelvin(prefix) => Some(format!("{}K", prefix.get_symbol())),
691 Celsius => Some(String::from("C")),
692 Fahrenheit => Some(String::from("F")),
693 Rankine => Some(String::from("R")),
694 }
695 }
696}
697
698impl UnitInfo for DataKind {
699 fn walk_values<F: FnMut(Self) -> MyResult<()>>(
700 multiply: bool,
701 _divide: bool,
702 mut function: F,
703 ) -> MyResult<()> {
704 PrefixKind::walk_values(multiply, false, |prefix| function(Byte(prefix)))?;
705 function(Bit)?;
706 Ok(())
707 }
708
709 fn get_factor(&self) -> BigRational {
710 match self {
711 Byte(prefix) => prefix.get_factor(),
712 Bit => create_ratio(1, 8),
713 }
714 }
715
716 fn get_name(&self) -> Option<String> {
717 match self {
718 Byte(prefix) => Some(format!("{}byte", prefix.get_name())),
719 Bit => Some(String::from("bit")),
720 }
721 }
722
723 fn get_symbol(&self) -> Option<String> {
724 match self {
725 Byte(prefix) => Some(format!("{}B", prefix.get_symbol())),
726 _ => None,
727 }
728 }
729}
730
731impl Meaning {
732 pub fn get_meanings() -> MyResult<Meanings> {
733 let meanings = RefCell::new(Meanings::new());
734 DeltaKind::walk_values(true, true, |unit| Self::insert_meaning(meanings.borrow_mut().deref_mut(), Delta(unit), unit))?;
735 LengthKind::walk_values(true, true, |unit| Self::insert_meaning(meanings.borrow_mut().deref_mut(), Length(unit), unit))?;
736 AreaKind::walk_values(true, true, |unit| Self::insert_meaning(meanings.borrow_mut().deref_mut(), Area(unit), unit))?;
737 VolumeKind::walk_values(true, true, |unit| Self::insert_meaning(meanings.borrow_mut().deref_mut(), Volume(unit), unit))?;
738 SpeedKind::walk_values(true, true, |unit| Self::insert_meaning(meanings.borrow_mut().deref_mut(), Speed(unit), unit))?;
739 MassKind::walk_values(true, true, |unit| Self::insert_meaning(meanings.borrow_mut().deref_mut(), Mass(unit), unit))?;
740 TempKind::walk_values(true, true, |unit| Self::insert_meaning(meanings.borrow_mut().deref_mut(), Temp(unit), unit))?;
741 DataKind::walk_values(true, true, |unit| Self::insert_meaning(meanings.borrow_mut().deref_mut(), Data(unit), unit))?;
742 Ok(meanings.into_inner())
743 }
744
745 fn insert_meaning<U: UnitInfo>(
746 meanings: &mut Meanings,
747 meaning: Self,
748 unit: U,
749 ) -> MyResult<()> {
750 if let Some(name) = unit.get_name() {
751 meanings.insert(name, meaning);
752 }
753 if let Some(symbol) = unit.get_symbol() {
754 meanings.insert(symbol, meaning);
755 }
756 Ok(())
757 }
758
759 pub fn get_symbol(&self) -> Option<String> {
760 match self {
761 Delta(unit) => unit.get_symbol().or_else(|| unit.get_name()),
762 Length(unit) => unit.get_symbol().or_else(|| unit.get_name()),
763 Area(unit) => unit.get_symbol().or_else(|| unit.get_name()),
764 Volume(unit) => unit.get_symbol().or_else(|| unit.get_name()),
765 Speed(unit) => unit.get_symbol().or_else(|| unit.get_name()),
766 Mass(unit) => unit.get_symbol().or_else(|| unit.get_name()),
767 Temp(unit) => unit.get_symbol().or_else(|| unit.get_name()),
768 Data(unit) => unit.get_symbol().or_else(|| unit.get_name()),
769 _ => None,
770 }
771 }
772
773 pub fn undo_meaning(self, number: &BigRational) -> Cow<BigRational> {
774 match self {
775 Delta(unit) => Self::undo_unit(number, unit),
776 Length(unit) => Self::undo_unit(number, unit),
777 Area(unit) => Self::undo_unit(number, unit),
778 Volume(unit) => Self::undo_unit(number, unit),
779 Speed(unit) => Self::undo_unit(number, unit),
780 Mass(unit) => Self::undo_unit(number, unit),
781 Temp(unit) => Self::undo_unit(number, unit),
782 Data(unit) => Self::undo_unit(number, unit),
783 _ => Cow::Borrowed(number),
784 }
785 }
786
787 pub fn redo_meaning(self, number: &BigRational) -> Cow<BigRational> {
788 match self {
789 Delta(unit) => Self::redo_unit(number, unit),
790 Length(unit) => Self::redo_unit(number, unit),
791 Area(unit) => Self::redo_unit(number, unit),
792 Volume(unit) => Self::redo_unit(number, unit),
793 Speed(unit) => Self::redo_unit(number, unit),
794 Mass(unit) => Self::redo_unit(number, unit),
795 Temp(unit) => Self::redo_unit(number, unit),
796 Data(unit) => Self::redo_unit(number, unit),
797 _ => Cow::Borrowed(number),
798 }
799 }
800
801 fn undo_unit<U: UnitInfo>(number: &BigRational, unit: U) -> Cow<BigRational> {
802 let factor = unit.get_factor();
803 let offset = unit.get_offset();
804 if let Some(result) = number.checked_mul(&factor).and_then(|n| n.checked_add(&offset)) {
805 Cow::Owned(result)
806 } else {
807 Cow::Borrowed(number)
808 }
809 }
810
811 fn redo_unit<U: UnitInfo>(number: &BigRational, unit: U) -> Cow<BigRational> {
812 let factor = unit.get_factor();
813 let offset = unit.get_offset();
814 if let Some(result) = number.checked_sub(&offset).and_then(|n| n.checked_div(&factor)) {
815 Cow::Owned(result)
816 } else {
817 Cow::Borrowed(number)
818 }
819 }
820
821 fn display_unit<U: UnitInfo>(f: &mut Formatter<'_>, unit: U, default: &str) -> std::fmt::Result {
822 if let Some(name) = unit.get_name() {
823 write!(f, "{}", name)
824 } else {
825 write!(f, "{}", default)
826 }
827 }
828
829 pub fn select_only_plain(self) -> Result<(), EngineError> {
830 if self == Plain {
831 Ok(())
832 } else {
833 Err(EngineError::BadCastOp(self, Plain))
834 }
835 }
836
837 pub fn select_not_time(self) -> Result<(), EngineError> {
838 if self != Time {
839 Ok(())
840 } else {
841 Err(EngineError::BadCastOp(Time, Time))
842 }
843 }
844
845 pub fn combine_cast_value(lhs: Self, rhs: Self) -> Option<Self> {
861 match (lhs, rhs) {
862 (_, Plain) => Some(Plain),
863 (Plain, rhs) => Some(rhs),
864 (Time, Time) => Some(Time),
865 (Delta(_), Delta(rhs)) => Some(Delta(rhs)),
866 (Length(_), Length(rhs)) => Some(Length(rhs)),
867 (Area(_), Area(rhs)) => Some(Area(rhs)),
868 (Volume(_), Volume(rhs)) => Some(Volume(rhs)),
869 (Speed(_), Speed(rhs)) => Some(Speed(rhs)),
870 (Mass(_), Mass(rhs)) => Some(Mass(rhs)),
871 (Temp(_), Temp(rhs)) => Some(Temp(rhs)),
872 (Data(_), Data(rhs)) => Some(Data(rhs)),
873 _ => None,
874 }
875 }
876
877 pub fn combine_add_time(lhs: Self, rhs: Self) -> Option<Self> {
884 match (lhs, rhs) {
885 (Plain, Plain) => Some(Plain),
886 (Plain, Delta(rhs)) => Some(Delta(rhs)),
887 (Plain, Time) => Some(Time),
888 (Delta(lhs), Plain) => Some(Delta(lhs)),
889 (Delta(lhs), Delta(_)) => Some(Delta(lhs)),
890 (Delta(_), Time) => Some(Time),
891 (Time, Plain) => Some(Time),
892 (Time, Delta(_)) => Some(Time),
893 _ => None,
894 }
895 }
896
897 pub fn combine_sub_time(lhs: Self, rhs: Self) -> Option<Self> {
904 match (lhs, rhs) {
905 (Plain, Plain) => Some(Plain),
906 (Plain, Delta(rhs)) => Some(Delta(rhs)),
907 (Delta(lhs), Plain) => Some(Delta(lhs)),
908 (Delta(lhs), Delta(_)) => Some(Delta(lhs)),
909 (Time, Plain) => Some(Time),
910 (Time, Delta(_)) => Some(Time),
911 (Time, Time) => Some(Delta(HMS)),
912 _ => None,
913 }
914 }
915
916 pub fn combine_mul_unit(lhs: Self, rhs: Self) -> Option<Self> {
928 match (lhs, rhs) {
929 (Plain, Plain) => Some(Plain),
930 (Plain, Delta(rhs)) => Some(Delta(rhs)),
931 (Delta(lhs), Plain) => Some(Delta(lhs)),
932 (Speed(Ratio(lhs, _)), Delta(_)) => Some(Length(lhs)),
933 (Length(lhs), Length(_)) => Some(Area(Square(lhs))),
934 (Length(lhs), Area(_)) => Some(Volume(Cubic(lhs))),
935 (Area(Square(lhs)), Length(_)) => Some(Volume(Cubic(lhs))),
936 (Delta(_), Speed(_)) => Some(Length(Metre(Unit))),
937 (Speed(_), Delta(_)) => Some(Length(Metre(Unit))),
938 (Area(_), Length(_)) => Some(Volume(Cubic(Metre(Unit)))),
939 _ => None,
940 }
941 }
942
943 pub fn combine_div_unit(lhs: Self, rhs: Self) -> Option<Self> {
959 match (lhs, rhs) {
960 (Plain, Plain) => Some(Plain),
961 (Delta(lhs), Plain) => Some(Delta(lhs)),
962 (Delta(_), Delta(_)) => Some(Plain),
963 (Length(_), Length(_)) => Some(Plain),
964 (Area(_), Area(_)) => Some(Plain),
965 (Volume(_), Volume(_)) => Some(Plain),
966 (Speed(_), Speed(_)) => Some(Plain),
967 (Mass(_), Mass(_)) => Some(Plain),
968 (Temp(_), Temp(_)) => Some(Plain),
969 (Data(_), Data(_)) => Some(Plain),
970 (Area(Square(lhs)), Length(_)) => Some(Length(lhs)),
971 (Volume(Cubic(lhs)), Length(_)) => Some(Area(Square(lhs))),
972 (Volume(Cubic(lhs)), Area(_)) => Some(Length(lhs)),
973 (Length(_), Speed(_)) => Some(Delta(Second(Unit))),
974 (Area(_), Length(_)) => Some(Length(Metre(Unit))),
975 (Volume(_), Length(_)) => Some(Area(Square(Metre(Unit)))),
976 (Volume(_), Area(_)) => Some(Length(Metre(Unit))),
977 _ => None,
978 }
979 }
980
981 pub fn combine_copy_left(lhs: Self, rhs: Self) -> Option<Self> {
997 match (lhs, rhs) {
998 (Plain, _) => None,
999 (Delta(_), _) => None,
1000 (Time, _) => None,
1001 (lhs, Plain) => Some(lhs),
1002 _ => None,
1003 }
1004 }
1005
1006 pub fn combine_copy_right(lhs: Self, rhs: Self) -> Option<Self> {
1012 match (lhs, rhs) {
1013 (_, Plain) => None,
1014 (_, Delta(_)) => None,
1015 (_, Time) => None,
1016 (Plain, rhs) => Some(rhs),
1017 _ => None,
1018 }
1019 }
1020
1021 pub fn combine_copy_same(lhs: Self, rhs: Self) -> Option<Self> {
1037 match (lhs, rhs) {
1038 (Length(lhs), Length(_)) => Some(Length(lhs)),
1039 (Area(lhs), Area(_)) => Some(Area(lhs)),
1040 (Volume(lhs), Volume(_)) => Some(Volume(lhs)),
1041 (Speed(lhs), Speed(_)) => Some(Speed(lhs)),
1042 (Mass(lhs), Mass(_)) => Some(Mass(lhs)),
1043 (Temp(lhs), Temp(_)) => Some(Temp(lhs)),
1044 (Data(lhs), Data(_)) => Some(Data(lhs)),
1045 _ => None,
1046 }
1047 }
1048
1049 pub fn combine_only_plain(lhs: Self, rhs: Self) -> Option<Self> {
1055 if (lhs, rhs) == (Plain, Plain) {
1056 Some(Plain)
1057 } else {
1058 None
1059 }
1060 }
1061}
1062
1063impl Display for Meaning {
1064 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1065 match self {
1066 Plain => write!(f, "plain"),
1067 Time => write!(f, "time"),
1068 Delta(unit) => Self::display_unit(f, *unit, "delta"),
1069 Length(unit) => Self::display_unit(f, *unit, "length"),
1070 Area(unit) => Self::display_unit(f, *unit, "area"),
1071 Volume(unit) => Self::display_unit(f, *unit, "volume"),
1072 Speed(unit) => Self::display_unit(f, *unit, "speed"),
1073 Mass(unit) => Self::display_unit(f, *unit, "mass"),
1074 Temp(unit) => Self::display_unit(f, *unit, "temp"),
1075 Data(unit) => Self::display_unit(f, *unit, "data"),
1076 }
1077 }
1078}
1079
1080#[cfg(test)]
1082mod tests {
1083 use crate::calc::context::Context;
1084 use crate::calc::meaning::AreaKind::*;
1085 use crate::calc::meaning::DataKind::*;
1086 use crate::calc::meaning::DeltaKind::*;
1087 use crate::calc::meaning::LengthKind::*;
1088 use crate::calc::meaning::MassKind::*;
1089 use crate::calc::meaning::Meaning;
1090 use crate::calc::meaning::Meaning::*;
1091 use crate::calc::meaning::PrefixKind::*;
1092 use crate::calc::meaning::SpeedKind::*;
1093 use crate::calc::meaning::TempKind::*;
1094 use crate::calc::meaning::VolumeKind::*;
1095 use crate::calc::value::tests::create_value;
1096 use crate::calc::value::{Value, ValueRef};
1097 use crate::error::EngineError::BadCastOp;
1098 use crate::error::{EngineError, MyError, MyResult};
1099 use crate::regex;
1100 use itertools::Itertools;
1101 use pretty_assertions::assert_eq;
1102 use std::cell::RefCell;
1103 use std::rc::Rc;
1104
1105 macro_rules! count_regex {
1106 ($meanings:ident, $regex:literal) => {
1107 {
1108 let regex = regex!($regex);
1109 $meanings.iter().filter(|x| regex.is_match(x)).count()
1110 }
1111 };
1112 }
1113
1114 #[test]
1115 fn test_meanings_are_collected_for_interface() {
1116 let meanings = get_meanings();
1117 assert_eq!(814, meanings.len());
1118 }
1119
1120 #[test]
1121 fn test_meanings_are_collected_with_multiplier_prefix() {
1122 let meanings = get_meanings();
1123 assert_eq!(6, count_regex!(meanings, r"^giga\w+$"));
1124 assert_eq!(6, count_regex!(meanings, r"^mega\w+$"));
1125 assert_eq!(6, count_regex!(meanings, r"^kilo\w+$"));
1126 assert_eq!(6, count_regex!(meanings, r"^G\w$"));
1127 assert_eq!(6, count_regex!(meanings, r"^M\w$"));
1128 assert_eq!(6, count_regex!(meanings, r"^k\w$"));
1129 }
1130
1131 #[test]
1132 fn test_meanings_are_collected_with_divider_prefix() {
1133 let meanings = get_meanings();
1134 assert_eq!(5, count_regex!(meanings, r"^milli\w+$"));
1135 assert_eq!(5, count_regex!(meanings, r"^micro\w+$"));
1136 assert_eq!(5, count_regex!(meanings, r"^nano\w+$"));
1137 assert_eq!(5, count_regex!(meanings, r"^m\w$"));
1138 assert_eq!(5, count_regex!(meanings, r"^u\w$"));
1139 assert_eq!(5, count_regex!(meanings, r"^n\w$"));
1140 }
1141
1142 #[test]
1143 fn test_meanings_are_collected_with_unit_measurement() {
1144 let meanings = get_meanings();
1145 assert_eq!(25, count_regex!(meanings, r"^\w*second$"));
1146 assert_eq!(25, count_regex!(meanings, r"^\w*metre$"));
1147 assert_eq!(25, count_regex!(meanings, r"^\w*litre$"));
1148 assert_eq!(25, count_regex!(meanings, r"^\w*gram$"));
1149 assert_eq!(25, count_regex!(meanings, r"^\w*kelvin$"));
1150 assert_eq!(13, count_regex!(meanings, r"^\w*byte$"));
1151 assert_eq!(25, count_regex!(meanings, r"^\w{0,2}s$"));
1152 assert_eq!(25, count_regex!(meanings, r"^\w{0,2}m$"));
1153 assert_eq!(25, count_regex!(meanings, r"^\w{0,2}l$"));
1154 assert_eq!(25, count_regex!(meanings, r"^\w{0,2}g$"));
1155 assert_eq!(25, count_regex!(meanings, r"^\w{0,2}K$"));
1156 assert_eq!(13, count_regex!(meanings, r"^\w{0,2}B$"));
1157 }
1158
1159 #[test]
1160 fn test_meanings_are_collected_with_square_measurement() {
1161 let meanings = get_meanings();
1162 assert_eq!(25, count_regex!(meanings, r"^square-\w*metre$"));
1163 assert_eq!(29, count_regex!(meanings, r"^square-\w+$"));
1164 assert_eq!(25, count_regex!(meanings, r"^\w{0,2}m\^2$"));
1165 assert_eq!(29, count_regex!(meanings, r"^\w+\^2$"));
1166 }
1167
1168 #[test]
1169 fn test_meanings_are_collected_with_cubic_measurement() {
1170 let meanings = get_meanings();
1171 assert_eq!(25, count_regex!(meanings, r"^cubic-\w*metre$"));
1172 assert_eq!(29, count_regex!(meanings, r"^cubic-\w+$"));
1173 assert_eq!(25, count_regex!(meanings, r"^\w{0,2}m\^3$"));
1174 assert_eq!(29, count_regex!(meanings, r"^\w+\^3$"));
1175 }
1176
1177 #[test]
1178 fn test_meanings_are_collected_with_ratio_measurement() {
1179 let meanings = get_meanings();
1180 assert_eq!(25, count_regex!(meanings, r"^\w*metre/\w*second$"));
1181 assert_eq!(25, count_regex!(meanings, r"^\w*metre/minute$"));
1182 assert_eq!(25, count_regex!(meanings, r"^\w*metre/hour$"));
1183 assert_eq!(25, count_regex!(meanings, r"^\w*metre/day$"));
1184 assert_eq!(25, count_regex!(meanings, r"^\w*metre/week$"));
1185 assert_eq!(25, count_regex!(meanings, r"^\w*metre/month$"));
1186 assert_eq!(25, count_regex!(meanings, r"^\w*metre/year$"));
1187 assert_eq!(25, count_regex!(meanings, r"^\w{0,2}m/\w*s$"));
1188 assert_eq!(25, count_regex!(meanings, r"^\w{0,2}m/minute$"));
1189 assert_eq!(25, count_regex!(meanings, r"^\w{0,2}m/hour$"));
1190 assert_eq!(25, count_regex!(meanings, r"^\w{0,2}m/day$"));
1191 assert_eq!(25, count_regex!(meanings, r"^\w{0,2}m/week$"));
1192 assert_eq!(25, count_regex!(meanings, r"^\w{0,2}m/month$"));
1193 assert_eq!(25, count_regex!(meanings, r"^\w{0,2}m/year$"));
1194 assert_eq!(29, count_regex!(meanings, r"^\w+/\w*s$"));
1195 assert_eq!(29, count_regex!(meanings, r"^\w+/\w*second$"));
1196 assert_eq!(54, count_regex!(meanings, r"^\w+/minute$"));
1197 assert_eq!(54, count_regex!(meanings, r"^\w+/hour$"));
1198 assert_eq!(54, count_regex!(meanings, r"^\w+/day$"));
1199 assert_eq!(54, count_regex!(meanings, r"^\w+/week$"));
1200 assert_eq!(54, count_regex!(meanings, r"^\w+/month$"));
1201 assert_eq!(54, count_regex!(meanings, r"^\w+/year$"));
1202 }
1203
1204 fn get_meanings() -> Vec<String> {
1205 let meanings = Meaning::get_meanings().unwrap_or_default();
1206 meanings.keys().map(String::from).sorted().collect::<Vec<_>>()
1207 }
1208
1209 #[test]
1225 fn test_unit_meanings_are_combined_on_cast() {
1226 assert_eq!(perform_cast_ok(Plain, Plain), Some(Plain));
1227 assert_eq!(perform_cast_ok(Plain, Delta(Hour)), Some(Delta(Hour)));
1228 assert_eq!(perform_cast_ok(Plain, Time), Some(Time));
1229 assert_eq!(perform_cast_ok(Plain, Length(Mile)), Some(Length(Mile)));
1230 assert_eq!(perform_cast_ok(Plain, Area(Acre)), Some(Area(Acre)));
1231 assert_eq!(perform_cast_ok(Plain, Volume(Pint)), Some(Volume(Pint)));
1232 assert_eq!(perform_cast_ok(Plain, Speed(Light)), Some(Speed(Light)));
1233 assert_eq!(perform_cast_ok(Plain, Mass(Ounce)), Some(Mass(Ounce)));
1234 assert_eq!(perform_cast_ok(Plain, Temp(Rankine)), Some(Temp(Rankine)));
1235 assert_eq!(perform_cast_ok(Plain, Data(Bit)), Some(Data(Bit)));
1236
1237 assert_eq!(perform_cast_ok(Delta(Hour), Plain), Some(Plain));
1238 assert_eq!(perform_cast_ok(Delta(Hour), Delta(Hour)), Some(Delta(Hour)));
1239 assert_eq!(perform_cast_err(Delta(Hour), Time), Some(BadCastOp(Delta(Hour), Time)));
1240 assert_eq!(perform_cast_err(Delta(Hour), Length(Mile)), Some(BadCastOp(Delta(Hour), Length(Mile))));
1241 assert_eq!(perform_cast_err(Delta(Hour), Area(Acre)), Some(BadCastOp(Delta(Hour), Area(Acre))));
1242 assert_eq!(perform_cast_err(Delta(Hour), Volume(Pint)), Some(BadCastOp(Delta(Hour), Volume(Pint))));
1243 assert_eq!(perform_cast_err(Delta(Hour), Speed(Light)), Some(BadCastOp(Delta(Hour), Speed(Light))));
1244 assert_eq!(perform_cast_err(Delta(Hour), Mass(Ounce)), Some(BadCastOp(Delta(Hour), Mass(Ounce))));
1245 assert_eq!(perform_cast_err(Delta(Hour), Temp(Rankine)), Some(BadCastOp(Delta(Hour), Temp(Rankine))));
1246 assert_eq!(perform_cast_err(Delta(Hour), Data(Bit)), Some(BadCastOp(Delta(Hour), Data(Bit))));
1247
1248 assert_eq!(perform_cast_ok(Time, Plain), Some(Plain));
1249 assert_eq!(perform_cast_err(Time, Delta(Hour)), Some(BadCastOp(Time, Delta(Hour))));
1250 assert_eq!(perform_cast_ok(Time, Time), Some(Time));
1251 assert_eq!(perform_cast_err(Time, Length(Mile)), Some(BadCastOp(Time, Length(Mile))));
1252 assert_eq!(perform_cast_err(Time, Area(Acre)), Some(BadCastOp(Time, Area(Acre))));
1253 assert_eq!(perform_cast_err(Time, Volume(Pint)), Some(BadCastOp(Time, Volume(Pint))));
1254 assert_eq!(perform_cast_err(Time, Speed(Light)), Some(BadCastOp(Time, Speed(Light))));
1255 assert_eq!(perform_cast_err(Time, Mass(Ounce)), Some(BadCastOp(Time, Mass(Ounce))));
1256 assert_eq!(perform_cast_err(Time, Temp(Rankine)), Some(BadCastOp(Time, Temp(Rankine))));
1257 assert_eq!(perform_cast_err(Time, Data(Bit)), Some(BadCastOp(Time, Data(Bit))));
1258
1259 assert_eq!(perform_cast_ok(Length(Mile), Plain), Some(Plain));
1260 assert_eq!(perform_cast_err(Length(Mile), Delta(Hour)), Some(BadCastOp(Length(Mile), Delta(Hour))));
1261 assert_eq!(perform_cast_err(Length(Mile), Time), Some(BadCastOp(Length(Mile), Time)));
1262 assert_eq!(perform_cast_ok(Length(Mile), Length(Mile)), Some(Length(Mile)));
1263 assert_eq!(perform_cast_err(Length(Mile), Area(Acre)), Some(BadCastOp(Length(Mile), Area(Acre))));
1264 assert_eq!(perform_cast_err(Length(Mile), Volume(Pint)), Some(BadCastOp(Length(Mile), Volume(Pint))));
1265 assert_eq!(perform_cast_err(Length(Mile), Speed(Light)), Some(BadCastOp(Length(Mile), Speed(Light))));
1266 assert_eq!(perform_cast_err(Length(Mile), Mass(Ounce)), Some(BadCastOp(Length(Mile), Mass(Ounce))));
1267 assert_eq!(perform_cast_err(Length(Mile), Temp(Rankine)), Some(BadCastOp(Length(Mile), Temp(Rankine))));
1268 assert_eq!(perform_cast_err(Length(Mile), Data(Bit)), Some(BadCastOp(Length(Mile), Data(Bit))));
1269
1270 assert_eq!(perform_cast_ok(Area(Acre), Plain), Some(Plain));
1271 assert_eq!(perform_cast_err(Area(Acre), Delta(Hour)), Some(BadCastOp(Area(Acre), Delta(Hour))));
1272 assert_eq!(perform_cast_err(Area(Acre), Time), Some(BadCastOp(Area(Acre), Time)));
1273 assert_eq!(perform_cast_err(Area(Acre), Length(Mile)), Some(BadCastOp(Area(Acre), Length(Mile))));
1274 assert_eq!(perform_cast_ok(Area(Acre), Area(Acre)), Some(Area(Acre)));
1275 assert_eq!(perform_cast_err(Area(Acre), Volume(Pint)), Some(BadCastOp(Area(Acre), Volume(Pint))));
1276 assert_eq!(perform_cast_err(Area(Acre), Speed(Light)), Some(BadCastOp(Area(Acre), Speed(Light))));
1277 assert_eq!(perform_cast_err(Area(Acre), Mass(Ounce)), Some(BadCastOp(Area(Acre), Mass(Ounce))));
1278 assert_eq!(perform_cast_err(Area(Acre), Temp(Rankine)), Some(BadCastOp(Area(Acre), Temp(Rankine))));
1279 assert_eq!(perform_cast_err(Area(Acre), Data(Bit)), Some(BadCastOp(Area(Acre), Data(Bit))));
1280
1281 assert_eq!(perform_cast_ok(Volume(Pint), Plain), Some(Plain));
1282 assert_eq!(perform_cast_err(Volume(Pint), Delta(Hour)), Some(BadCastOp(Volume(Pint), Delta(Hour))));
1283 assert_eq!(perform_cast_err(Volume(Pint), Time), Some(BadCastOp(Volume(Pint), Time)));
1284 assert_eq!(perform_cast_err(Volume(Pint), Length(Mile)), Some(BadCastOp(Volume(Pint), Length(Mile))));
1285 assert_eq!(perform_cast_err(Volume(Pint), Area(Acre)), Some(BadCastOp(Volume(Pint), Area(Acre))));
1286 assert_eq!(perform_cast_ok(Volume(Pint), Volume(Pint)), Some(Volume(Pint)));
1287 assert_eq!(perform_cast_err(Volume(Pint), Speed(Light)), Some(BadCastOp(Volume(Pint), Speed(Light))));
1288 assert_eq!(perform_cast_err(Volume(Pint), Mass(Ounce)), Some(BadCastOp(Volume(Pint), Mass(Ounce))));
1289 assert_eq!(perform_cast_err(Volume(Pint), Temp(Rankine)), Some(BadCastOp(Volume(Pint), Temp(Rankine))));
1290 assert_eq!(perform_cast_err(Volume(Pint), Data(Bit)), Some(BadCastOp(Volume(Pint), Data(Bit))));
1291
1292 assert_eq!(perform_cast_ok(Speed(Light), Plain), Some(Plain));
1293 assert_eq!(perform_cast_err(Speed(Light), Delta(Hour)), Some(BadCastOp(Speed(Light), Delta(Hour))));
1294 assert_eq!(perform_cast_err(Speed(Light), Time), Some(BadCastOp(Speed(Light), Time)));
1295 assert_eq!(perform_cast_err(Speed(Light), Length(Mile)), Some(BadCastOp(Speed(Light), Length(Mile))));
1296 assert_eq!(perform_cast_err(Speed(Light), Area(Acre)), Some(BadCastOp(Speed(Light), Area(Acre))));
1297 assert_eq!(perform_cast_err(Speed(Light), Volume(Pint)), Some(BadCastOp(Speed(Light), Volume(Pint))));
1298 assert_eq!(perform_cast_ok(Speed(Light), Speed(Light)), Some(Speed(Light)));
1299 assert_eq!(perform_cast_err(Speed(Light), Mass(Ounce)), Some(BadCastOp(Speed(Light), Mass(Ounce))));
1300 assert_eq!(perform_cast_err(Speed(Light), Temp(Rankine)), Some(BadCastOp(Speed(Light), Temp(Rankine))));
1301 assert_eq!(perform_cast_err(Speed(Light), Data(Bit)), Some(BadCastOp(Speed(Light), Data(Bit))));
1302
1303 assert_eq!(perform_cast_ok(Mass(Ounce), Plain), Some(Plain));
1304 assert_eq!(perform_cast_err(Mass(Ounce), Delta(Hour)), Some(BadCastOp(Mass(Ounce), Delta(Hour))));
1305 assert_eq!(perform_cast_err(Mass(Ounce), Time), Some(BadCastOp(Mass(Ounce), Time)));
1306 assert_eq!(perform_cast_err(Mass(Ounce), Length(Mile)), Some(BadCastOp(Mass(Ounce), Length(Mile))));
1307 assert_eq!(perform_cast_err(Mass(Ounce), Area(Acre)), Some(BadCastOp(Mass(Ounce), Area(Acre))));
1308 assert_eq!(perform_cast_err(Mass(Ounce), Volume(Pint)), Some(BadCastOp(Mass(Ounce), Volume(Pint))));
1309 assert_eq!(perform_cast_err(Mass(Ounce), Speed(Light)), Some(BadCastOp(Mass(Ounce), Speed(Light))));
1310 assert_eq!(perform_cast_ok(Mass(Ounce), Mass(Ounce)), Some(Mass(Ounce)));
1311 assert_eq!(perform_cast_err(Mass(Ounce), Temp(Rankine)), Some(BadCastOp(Mass(Ounce), Temp(Rankine))));
1312 assert_eq!(perform_cast_err(Mass(Ounce), Data(Bit)), Some(BadCastOp(Mass(Ounce), Data(Bit))));
1313
1314 assert_eq!(perform_cast_ok(Temp(Rankine), Plain), Some(Plain));
1315 assert_eq!(perform_cast_err(Temp(Rankine), Delta(Hour)), Some(BadCastOp(Temp(Rankine), Delta(Hour))));
1316 assert_eq!(perform_cast_err(Temp(Rankine), Time), Some(BadCastOp(Temp(Rankine), Time)));
1317 assert_eq!(perform_cast_err(Temp(Rankine), Length(Mile)), Some(BadCastOp(Temp(Rankine), Length(Mile))));
1318 assert_eq!(perform_cast_err(Temp(Rankine), Area(Acre)), Some(BadCastOp(Temp(Rankine), Area(Acre))));
1319 assert_eq!(perform_cast_err(Temp(Rankine), Volume(Pint)), Some(BadCastOp(Temp(Rankine), Volume(Pint))));
1320 assert_eq!(perform_cast_err(Temp(Rankine), Speed(Light)), Some(BadCastOp(Temp(Rankine), Speed(Light))));
1321 assert_eq!(perform_cast_err(Temp(Rankine), Mass(Ounce)), Some(BadCastOp(Temp(Rankine), Mass(Ounce))));
1322 assert_eq!(perform_cast_ok(Temp(Rankine), Temp(Rankine)), Some(Temp(Rankine)));
1323 assert_eq!(perform_cast_err(Temp(Rankine), Data(Bit)), Some(BadCastOp(Temp(Rankine), Data(Bit))));
1324
1325 assert_eq!(perform_cast_ok(Data(Bit), Plain), Some(Plain));
1326 assert_eq!(perform_cast_err(Data(Bit), Delta(Hour)), Some(BadCastOp(Data(Bit), Delta(Hour))));
1327 assert_eq!(perform_cast_err(Data(Bit), Time), Some(BadCastOp(Data(Bit), Time)));
1328 assert_eq!(perform_cast_err(Data(Bit), Length(Mile)), Some(BadCastOp(Data(Bit), Length(Mile))));
1329 assert_eq!(perform_cast_err(Data(Bit), Area(Acre)), Some(BadCastOp(Data(Bit), Area(Acre))));
1330 assert_eq!(perform_cast_err(Data(Bit), Volume(Pint)), Some(BadCastOp(Data(Bit), Volume(Pint))));
1331 assert_eq!(perform_cast_err(Data(Bit), Speed(Light)), Some(BadCastOp(Data(Bit), Speed(Light))));
1332 assert_eq!(perform_cast_err(Data(Bit), Mass(Ounce)), Some(BadCastOp(Data(Bit), Mass(Ounce))));
1333 assert_eq!(perform_cast_err(Data(Bit), Temp(Rankine)), Some(BadCastOp(Data(Bit), Temp(Rankine))));
1334 assert_eq!(perform_cast_ok(Data(Bit), Data(Bit)), Some(Data(Bit)));
1335 }
1336
1337 #[test]
1338 fn test_delta_values_are_scaled_on_cast() {
1339 assert_eq!(perform_cast_value(Delta(Second(Unit)), Delta(Second(Unit))), Some((Delta(Second(Unit)), String::from("1.0"))));
1340 assert_eq!(perform_cast_value(Delta(Minute), Delta(Second(Unit))), Some((Delta(Second(Unit)), String::from("60.0"))));
1341 assert_eq!(perform_cast_value(Delta(Hour), Delta(Second(Unit))), Some((Delta(Second(Unit)), String::from("3600.0"))));
1342 assert_eq!(perform_cast_value(Delta(Day), Delta(Second(Unit))), Some((Delta(Second(Unit)), String::from("86400.0"))));
1343 assert_eq!(perform_cast_value(Delta(Week), Delta(Second(Unit))), Some((Delta(Second(Unit)), String::from("604800.0"))));
1344 assert_eq!(perform_cast_value(Delta(Month), Delta(Second(Unit))), Some((Delta(Second(Unit)), String::from("2592000.0"))));
1345 assert_eq!(perform_cast_value(Delta(Year), Delta(Second(Unit))), Some((Delta(Second(Unit)), String::from("31557600.0"))));
1346 assert_eq!(perform_cast_value(Delta(HMS), Delta(Second(Unit))), Some((Delta(Second(Unit)), String::from("1.0"))));
1347
1348 assert_eq!(perform_cast_value(Delta(Second(Milli)), Delta(Second(Milli))), Some((Delta(Second(Milli)), String::from("1.0"))));
1349 assert_eq!(perform_cast_value(Delta(Second(Milli)), Delta(Minute)), Some((Delta(Minute), String::from("0.000016667"))));
1350 assert_eq!(perform_cast_value(Delta(Second(Milli)), Delta(HMS)), Some((Delta(HMS), String::from("00.001"))));
1351
1352 assert_eq!(perform_cast_value(Delta(Minute), Delta(Second(Milli))), Some((Delta(Second(Milli)), String::from("60000.0"))));
1353 assert_eq!(perform_cast_value(Delta(Minute), Delta(Minute)), Some((Delta(Minute), String::from("1.0"))));
1354 assert_eq!(perform_cast_value(Delta(Minute), Delta(HMS)), Some((Delta(HMS), String::from("01:00.000"))));
1355
1356 assert_eq!(perform_cast_value(Delta(HMS), Delta(Second(Milli))), Some((Delta(Second(Milli)), String::from("1000.0"))));
1357 assert_eq!(perform_cast_value(Delta(HMS), Delta(Minute)), Some((Delta(Minute), String::from("0.016666667"))));
1358 assert_eq!(perform_cast_value(Delta(HMS), Delta(HMS)), Some((Delta(HMS), String::from("01.000"))));
1359 }
1360
1361 #[test]
1362 fn test_length_values_are_scaled_on_cast() {
1363 assert_eq!(perform_cast_value(Length(Metre(Unit)), Length(Metre(Unit))), Some((Length(Metre(Unit)), String::from("1.0"))));
1364 assert_eq!(perform_cast_value(Length(Inch), Length(Metre(Unit))), Some((Length(Metre(Unit)), String::from("0.0254"))));
1365 assert_eq!(perform_cast_value(Length(Foot), Length(Metre(Unit))), Some((Length(Metre(Unit)), String::from("0.3048"))));
1366 assert_eq!(perform_cast_value(Length(Yard), Length(Metre(Unit))), Some((Length(Metre(Unit)), String::from("0.9144"))));
1367 assert_eq!(perform_cast_value(Length(Mile), Length(Metre(Unit))), Some((Length(Metre(Unit)), String::from("1609.344"))));
1368
1369 assert_eq!(perform_cast_value(Length(Metre(Kilo)), Length(Metre(Kilo))), Some((Length(Metre(Kilo)), String::from("1.0"))));
1370 assert_eq!(perform_cast_value(Length(Metre(Kilo)), Length(Mile)), Some((Length(Mile), String::from("0.621371192"))));
1371
1372 assert_eq!(perform_cast_value(Length(Mile), Length(Metre(Kilo))), Some((Length(Metre(Kilo)), String::from("1.609344"))));
1373 assert_eq!(perform_cast_value(Length(Mile), Length(Mile)), Some((Length(Mile), String::from("1.0"))));
1374 }
1375
1376 #[test]
1377 fn test_area_values_are_scaled_on_cast() {
1378 assert_eq!(perform_cast_value(Area(Square(Metre(Unit))), Area(Square(Metre(Unit)))), Some((Area(Square(Metre(Unit))), String::from("1.0"))));
1379 assert_eq!(perform_cast_value(Area(Hectare), Area(Square(Metre(Unit)))), Some((Area(Square(Metre(Unit))), String::from("10000.0"))));
1380 assert_eq!(perform_cast_value(Area(Acre), Area(Square(Metre(Unit)))), Some((Area(Square(Metre(Unit))), String::from("4046.8564224"))));
1381
1382 assert_eq!(perform_cast_value(Area(Square(Metre(Kilo))), Area(Square(Metre(Kilo)))), Some((Area(Square(Metre(Kilo))), String::from("1.0"))));
1383 assert_eq!(perform_cast_value(Area(Square(Metre(Kilo))), Area(Square(Mile))), Some((Area(Square(Mile)), String::from("0.386102159"))));
1384 assert_eq!(perform_cast_value(Area(Square(Metre(Kilo))), Area(Acre)), Some((Area(Acre), String::from("247.105381467"))));
1385
1386 assert_eq!(perform_cast_value(Area(Square(Mile)), Area(Square(Metre(Kilo)))), Some((Area(Square(Metre(Kilo))), String::from("2.58998811"))));
1387 assert_eq!(perform_cast_value(Area(Square(Mile)), Area(Square(Mile))), Some((Area(Square(Mile)), String::from("1.0"))));
1388 assert_eq!(perform_cast_value(Area(Square(Mile)), Area(Acre)), Some((Area(Acre), String::from("640.0"))));
1389
1390 assert_eq!(perform_cast_value(Area(Acre), Area(Square(Metre(Kilo)))), Some((Area(Square(Metre(Kilo))), String::from("0.004046856"))));
1391 assert_eq!(perform_cast_value(Area(Acre), Area(Square(Mile))), Some((Area(Square(Mile)), String::from("0.0015625"))));
1392 assert_eq!(perform_cast_value(Area(Acre), Area(Acre)), Some((Area(Acre), String::from("1.0"))));
1393 }
1394
1395 #[test]
1396 fn test_volume_values_are_scaled_on_cast() {
1397 assert_eq!(perform_cast_value(Volume(Cubic(Metre(Unit))), Volume(Cubic(Metre(Unit)))), Some((Volume(Cubic(Metre(Unit))), String::from("1.0"))));
1398 assert_eq!(perform_cast_value(Volume(Litre(Unit)), Volume(Cubic(Metre(Unit)))), Some((Volume(Cubic(Metre(Unit))), String::from("0.001"))));
1399 assert_eq!(perform_cast_value(Volume(Tsp), Volume(Cubic(Metre(Unit)))), Some((Volume(Cubic(Metre(Unit))), String::from("0.000005919"))));
1400 assert_eq!(perform_cast_value(Volume(Tbsp), Volume(Cubic(Metre(Unit)))), Some((Volume(Cubic(Metre(Unit))), String::from("0.000017758"))));
1401 assert_eq!(perform_cast_value(Volume(Floz), Volume(Cubic(Metre(Unit)))), Some((Volume(Cubic(Metre(Unit))), String::from("0.000028413"))));
1402 assert_eq!(perform_cast_value(Volume(Pint), Volume(Cubic(Metre(Unit)))), Some((Volume(Cubic(Metre(Unit))), String::from("0.000568261"))));
1403 assert_eq!(perform_cast_value(Volume(Quart), Volume(Cubic(Metre(Unit)))), Some((Volume(Cubic(Metre(Unit))), String::from("0.001136523"))));
1404 assert_eq!(perform_cast_value(Volume(Gallon), Volume(Cubic(Metre(Unit)))), Some((Volume(Cubic(Metre(Unit))), String::from("0.00454609"))));
1405 assert_eq!(perform_cast_value(Volume(Barrel), Volume(Cubic(Metre(Unit)))), Some((Volume(Cubic(Metre(Unit))), String::from("0.16365924"))));
1406 assert_eq!(perform_cast_value(Volume(USTsp), Volume(Cubic(Metre(Unit)))), Some((Volume(Cubic(Metre(Unit))), String::from("0.000004929"))));
1407 assert_eq!(perform_cast_value(Volume(USTbsp), Volume(Cubic(Metre(Unit)))), Some((Volume(Cubic(Metre(Unit))), String::from("0.000014787"))));
1408 assert_eq!(perform_cast_value(Volume(USFloz), Volume(Cubic(Metre(Unit)))), Some((Volume(Cubic(Metre(Unit))), String::from("0.000029574"))));
1409 assert_eq!(perform_cast_value(Volume(USCup), Volume(Cubic(Metre(Unit)))), Some((Volume(Cubic(Metre(Unit))), String::from("0.000236588"))));
1410 assert_eq!(perform_cast_value(Volume(USPint), Volume(Cubic(Metre(Unit)))), Some((Volume(Cubic(Metre(Unit))), String::from("0.000473176"))));
1411 assert_eq!(perform_cast_value(Volume(USQuart), Volume(Cubic(Metre(Unit)))), Some((Volume(Cubic(Metre(Unit))), String::from("0.000946353"))));
1412 assert_eq!(perform_cast_value(Volume(USGallon), Volume(Cubic(Metre(Unit)))), Some((Volume(Cubic(Metre(Unit))), String::from("0.003785412"))));
1413 assert_eq!(perform_cast_value(Volume(USBarrel), Volume(Cubic(Metre(Unit)))), Some((Volume(Cubic(Metre(Unit))), String::from("0.119240471"))));
1414
1415 assert_eq!(perform_cast_value(Volume(Cubic(Metre(Unit))), Volume(Cubic(Metre(Unit)))), Some((Volume(Cubic(Metre(Unit))), String::from("1.0"))));
1416 assert_eq!(perform_cast_value(Volume(Cubic(Metre(Unit))), Volume(Cubic(Yard))), Some((Volume(Cubic(Yard)), String::from("1.307950619"))));
1417 assert_eq!(perform_cast_value(Volume(Cubic(Metre(Unit))), Volume(Litre(Unit))), Some((Volume(Litre(Unit)), String::from("1000.0"))));
1418 assert_eq!(perform_cast_value(Volume(Cubic(Metre(Unit))), Volume(Pint)), Some((Volume(Pint), String::from("1759.753986393"))));
1419
1420 assert_eq!(perform_cast_value(Volume(Cubic(Yard)), Volume(Cubic(Metre(Unit)))), Some((Volume(Cubic(Metre(Unit))), String::from("0.764554858"))));
1421 assert_eq!(perform_cast_value(Volume(Cubic(Yard)), Volume(Cubic(Yard))), Some((Volume(Cubic(Yard)), String::from("1.0"))));
1422 assert_eq!(perform_cast_value(Volume(Cubic(Yard)), Volume(Litre(Unit))), Some((Volume(Litre(Unit)), String::from("764.554857984"))));
1423 assert_eq!(perform_cast_value(Volume(Cubic(Yard)), Volume(Pint)), Some((Volume(Pint), String::from("1345.428459153"))));
1424
1425 assert_eq!(perform_cast_value(Volume(Litre(Unit)), Volume(Cubic(Metre(Unit)))), Some((Volume(Cubic(Metre(Unit))), String::from("0.001"))));
1426 assert_eq!(perform_cast_value(Volume(Litre(Unit)), Volume(Cubic(Yard))), Some((Volume(Cubic(Yard)), String::from("0.001307951"))));
1427 assert_eq!(perform_cast_value(Volume(Litre(Unit)), Volume(Litre(Unit))), Some((Volume(Litre(Unit)), String::from("1.0"))));
1428 assert_eq!(perform_cast_value(Volume(Litre(Unit)), Volume(Pint)), Some((Volume(Pint), String::from("1.759753986"))));
1429
1430 assert_eq!(perform_cast_value(Volume(Pint), Volume(Cubic(Metre(Unit)))), Some((Volume(Cubic(Metre(Unit))), String::from("0.000568261"))));
1431 assert_eq!(perform_cast_value(Volume(Pint), Volume(Cubic(Yard))), Some((Volume(Cubic(Yard)), String::from("0.000743258"))));
1432 assert_eq!(perform_cast_value(Volume(Pint), Volume(Litre(Unit))), Some((Volume(Litre(Unit)), String::from("0.56826125"))));
1433 assert_eq!(perform_cast_value(Volume(Pint), Volume(Pint)), Some((Volume(Pint), String::from("1.0"))));
1434 }
1435
1436 #[test]
1437 fn test_speed_values_are_scaled_on_cast() {
1438 assert_eq!(perform_cast_value(Speed(Ratio(Metre(Unit), Second(Unit))), Speed(Ratio(Metre(Unit), Second(Unit)))), Some((Speed(Ratio(Metre(Unit), Second(Unit))), String::from("1.0"))));
1439 assert_eq!(perform_cast_value(Speed(Mach), Speed(Ratio(Metre(Unit), Second(Unit)))), Some((Speed(Ratio(Metre(Unit), Second(Unit))), String::from("340.0"))));
1440 assert_eq!(perform_cast_value(Speed(Light), Speed(Ratio(Metre(Unit), Second(Unit)))), Some((Speed(Ratio(Metre(Unit), Second(Unit))), String::from("299792458.0"))));
1441
1442 assert_eq!(perform_cast_value(Speed(Ratio(Metre(Kilo), Hour)), Speed(Ratio(Metre(Kilo), Hour))), Some((Speed(Ratio(Metre(Kilo), Hour)), String::from("1.0"))));
1443 assert_eq!(perform_cast_value(Speed(Ratio(Metre(Kilo), Hour)), Speed(Ratio(Mile, Hour))), Some((Speed(Ratio(Mile, Hour)), String::from("0.621371192"))));
1444 assert_eq!(perform_cast_value(Speed(Ratio(Metre(Kilo), Hour)), Speed(Mach)), Some((Speed(Mach), String::from("0.000816993"))));
1445
1446 assert_eq!(perform_cast_value(Speed(Ratio(Mile, Hour)), Speed(Ratio(Metre(Kilo), Hour))), Some((Speed(Ratio(Metre(Kilo), Hour)), String::from("1.609344"))));
1447 assert_eq!(perform_cast_value(Speed(Ratio(Mile, Hour)), Speed(Ratio(Mile, Hour))), Some((Speed(Ratio(Mile, Hour)), String::from("1.0"))));
1448 assert_eq!(perform_cast_value(Speed(Ratio(Mile, Hour)), Speed(Mach)), Some((Speed(Mach), String::from("0.001314824"))));
1449
1450 assert_eq!(perform_cast_value(Speed(Mach), Speed(Ratio(Metre(Kilo), Hour))), Some((Speed(Ratio(Metre(Kilo), Hour)), String::from("1224.0"))));
1451 assert_eq!(perform_cast_value(Speed(Mach), Speed(Ratio(Mile, Hour))), Some((Speed(Ratio(Mile, Hour)), String::from("760.558339298"))));
1452 assert_eq!(perform_cast_value(Speed(Mach), Speed(Mach)), Some((Speed(Mach), String::from("1.0"))));
1453 }
1454
1455 #[test]
1456 fn test_mass_values_are_scaled_on_cast() {
1457 assert_eq!(perform_cast_value(Mass(Gram(Unit)), Mass(Gram(Unit))), Some((Mass(Gram(Unit)), String::from("1.0"))));
1458 assert_eq!(perform_cast_value(Mass(Ounce), Mass(Gram(Unit))), Some((Mass(Gram(Unit)), String::from("28.349523125"))));
1459 assert_eq!(perform_cast_value(Mass(Pound), Mass(Gram(Unit))), Some((Mass(Gram(Unit)), String::from("453.59237"))));
1460 assert_eq!(perform_cast_value(Mass(Stone), Mass(Gram(Unit))), Some((Mass(Gram(Unit)), String::from("6350.29318"))));
1461 assert_eq!(perform_cast_value(Mass(Ton), Mass(Gram(Unit))), Some((Mass(Gram(Unit)), String::from("1016046.9088"))));
1462
1463 assert_eq!(perform_cast_value(Mass(Gram(Kilo)), Mass(Gram(Kilo))), Some((Mass(Gram(Kilo)), String::from("1.0"))));
1464 assert_eq!(perform_cast_value(Mass(Gram(Kilo)), Mass(Ton)), Some((Mass(Ton), String::from("0.000984207"))));
1465
1466 assert_eq!(perform_cast_value(Mass(Ton), Mass(Gram(Kilo))), Some((Mass(Gram(Kilo)), String::from("1016.0469088"))));
1467 assert_eq!(perform_cast_value(Mass(Ton), Mass(Ton)), Some((Mass(Ton), String::from("1.0"))));
1468 }
1469
1470 #[test]
1471 fn test_temp_values_are_scaled_on_cast() {
1472 assert_eq!(perform_cast_temp(Temp(Kelvin(Unit)), Temp(Kelvin(Unit)), "0.0"), Some((Temp(Kelvin(Unit)), String::from("0.0"))));
1473 assert_eq!(perform_cast_temp(Temp(Kelvin(Unit)), Temp(Kelvin(Unit)), "50.0"), Some((Temp(Kelvin(Unit)), String::from("50.0"))));
1474 assert_eq!(perform_cast_temp(Temp(Kelvin(Unit)), Temp(Kelvin(Unit)), "100.0"), Some((Temp(Kelvin(Unit)), String::from("100.0"))));
1475
1476 assert_eq!(perform_cast_temp(Temp(Kelvin(Unit)), Temp(Celsius), "0.0"), Some((Temp(Celsius), String::from("-273.15"))));
1477 assert_eq!(perform_cast_temp(Temp(Kelvin(Unit)), Temp(Celsius), "50.0"), Some((Temp(Celsius), String::from("-223.15"))));
1478 assert_eq!(perform_cast_temp(Temp(Kelvin(Unit)), Temp(Celsius), "100.0"), Some((Temp(Celsius), String::from("-173.15"))));
1479
1480 assert_eq!(perform_cast_temp(Temp(Kelvin(Unit)), Temp(Fahrenheit), "0.0"), Some((Temp(Fahrenheit), String::from("-459.67"))));
1481 assert_eq!(perform_cast_temp(Temp(Kelvin(Unit)), Temp(Fahrenheit), "50.0"), Some((Temp(Fahrenheit), String::from("-369.67"))));
1482 assert_eq!(perform_cast_temp(Temp(Kelvin(Unit)), Temp(Fahrenheit), "100.0"), Some((Temp(Fahrenheit), String::from("-279.67"))));
1483
1484 assert_eq!(perform_cast_temp(Temp(Kelvin(Unit)), Temp(Rankine), "0.0"), Some((Temp(Rankine), String::from("0.0"))));
1485 assert_eq!(perform_cast_temp(Temp(Kelvin(Unit)), Temp(Rankine), "50.0"), Some((Temp(Rankine), String::from("90.0"))));
1486 assert_eq!(perform_cast_temp(Temp(Kelvin(Unit)), Temp(Rankine), "100.0"), Some((Temp(Rankine), String::from("180.0"))));
1487
1488 assert_eq!(perform_cast_temp(Temp(Celsius), Temp(Kelvin(Unit)), "0.0"), Some((Temp(Kelvin(Unit)), String::from("273.15"))));
1489 assert_eq!(perform_cast_temp(Temp(Celsius), Temp(Kelvin(Unit)), "50.0"), Some((Temp(Kelvin(Unit)), String::from("323.15"))));
1490 assert_eq!(perform_cast_temp(Temp(Celsius), Temp(Kelvin(Unit)), "100.0"), Some((Temp(Kelvin(Unit)), String::from("373.15"))));
1491
1492 assert_eq!(perform_cast_temp(Temp(Celsius), Temp(Celsius), "0.0"), Some((Temp(Celsius), String::from("0.0"))));
1493 assert_eq!(perform_cast_temp(Temp(Celsius), Temp(Celsius), "50.0"), Some((Temp(Celsius), String::from("50.0"))));
1494 assert_eq!(perform_cast_temp(Temp(Celsius), Temp(Celsius), "100.0"), Some((Temp(Celsius), String::from("100.0"))));
1495
1496 assert_eq!(perform_cast_temp(Temp(Celsius), Temp(Fahrenheit), "0.0"), Some((Temp(Fahrenheit), String::from("32.0"))));
1497 assert_eq!(perform_cast_temp(Temp(Celsius), Temp(Fahrenheit), "50.0"), Some((Temp(Fahrenheit), String::from("122.0"))));
1498 assert_eq!(perform_cast_temp(Temp(Celsius), Temp(Fahrenheit), "100.0"), Some((Temp(Fahrenheit), String::from("212.0"))));
1499
1500 assert_eq!(perform_cast_temp(Temp(Celsius), Temp(Rankine), "0.0"), Some((Temp(Rankine), String::from("491.67"))));
1501 assert_eq!(perform_cast_temp(Temp(Celsius), Temp(Rankine), "50.0"), Some((Temp(Rankine), String::from("581.67"))));
1502 assert_eq!(perform_cast_temp(Temp(Celsius), Temp(Rankine), "100.0"), Some((Temp(Rankine), String::from("671.67"))));
1503
1504 assert_eq!(perform_cast_temp(Temp(Fahrenheit), Temp(Kelvin(Unit)), "0.0"), Some((Temp(Kelvin(Unit)), String::from("255.372222222"))));
1505 assert_eq!(perform_cast_temp(Temp(Fahrenheit), Temp(Kelvin(Unit)), "50.0"), Some((Temp(Kelvin(Unit)), String::from("283.15"))));
1506 assert_eq!(perform_cast_temp(Temp(Fahrenheit), Temp(Kelvin(Unit)), "100.0"), Some((Temp(Kelvin(Unit)), String::from("310.927777778"))));
1507
1508 assert_eq!(perform_cast_temp(Temp(Fahrenheit), Temp(Celsius), "0.0"), Some((Temp(Celsius), String::from("-17.777777778"))));
1509 assert_eq!(perform_cast_temp(Temp(Fahrenheit), Temp(Celsius), "50.0"), Some((Temp(Celsius), String::from("10.0"))));
1510 assert_eq!(perform_cast_temp(Temp(Fahrenheit), Temp(Celsius), "100.0"), Some((Temp(Celsius), String::from("37.777777778"))));
1511
1512 assert_eq!(perform_cast_temp(Temp(Fahrenheit), Temp(Fahrenheit), "0.0"), Some((Temp(Fahrenheit), String::from("0.0"))));
1513 assert_eq!(perform_cast_temp(Temp(Fahrenheit), Temp(Fahrenheit), "50.0"), Some((Temp(Fahrenheit), String::from("50.0"))));
1514 assert_eq!(perform_cast_temp(Temp(Fahrenheit), Temp(Fahrenheit), "100.0"), Some((Temp(Fahrenheit), String::from("100.0"))));
1515
1516 assert_eq!(perform_cast_temp(Temp(Fahrenheit), Temp(Rankine), "0.0"), Some((Temp(Rankine), String::from("459.67"))));
1517 assert_eq!(perform_cast_temp(Temp(Fahrenheit), Temp(Rankine), "50.0"), Some((Temp(Rankine), String::from("509.67"))));
1518 assert_eq!(perform_cast_temp(Temp(Fahrenheit), Temp(Rankine), "100.0"), Some((Temp(Rankine), String::from("559.67"))));
1519
1520 assert_eq!(perform_cast_temp(Temp(Rankine), Temp(Kelvin(Unit)), "0.0"), Some((Temp(Kelvin(Unit)), String::from("0.0"))));
1521 assert_eq!(perform_cast_temp(Temp(Rankine), Temp(Kelvin(Unit)), "50.0"), Some((Temp(Kelvin(Unit)), String::from("27.777777778"))));
1522 assert_eq!(perform_cast_temp(Temp(Rankine), Temp(Kelvin(Unit)), "100.0"), Some((Temp(Kelvin(Unit)), String::from("55.555555556"))));
1523
1524 assert_eq!(perform_cast_temp(Temp(Rankine), Temp(Celsius), "0.0"), Some((Temp(Celsius), String::from("-273.15"))));
1525 assert_eq!(perform_cast_temp(Temp(Rankine), Temp(Celsius), "50.0"), Some((Temp(Celsius), String::from("-245.372222222"))));
1526 assert_eq!(perform_cast_temp(Temp(Rankine), Temp(Celsius), "100.0"), Some((Temp(Celsius), String::from("-217.594444444"))));
1527
1528 assert_eq!(perform_cast_temp(Temp(Rankine), Temp(Fahrenheit), "0.0"), Some((Temp(Fahrenheit), String::from("-459.67"))));
1529 assert_eq!(perform_cast_temp(Temp(Rankine), Temp(Fahrenheit), "50.0"), Some((Temp(Fahrenheit), String::from("-409.67"))));
1530 assert_eq!(perform_cast_temp(Temp(Rankine), Temp(Fahrenheit), "100.0"), Some((Temp(Fahrenheit), String::from("-359.67"))));
1531
1532 assert_eq!(perform_cast_temp(Temp(Rankine), Temp(Rankine), "0.0"), Some((Temp(Rankine), String::from("0.0"))));
1533 assert_eq!(perform_cast_temp(Temp(Rankine), Temp(Rankine), "50.0"), Some((Temp(Rankine), String::from("50.0"))));
1534 assert_eq!(perform_cast_temp(Temp(Rankine), Temp(Rankine), "100.0"), Some((Temp(Rankine), String::from("100.0"))));
1535 }
1536
1537 #[test]
1538 fn test_data_values_are_scaled_on_cast() {
1539 assert_eq!(perform_cast_value(Data(Byte(Unit)), Data(Byte(Unit))), Some((Data(Byte(Unit)), String::from("1.0"))));
1540 assert_eq!(perform_cast_value(Data(Bit), Data(Byte(Unit))), Some((Data(Byte(Unit)), String::from("0.125"))));
1541
1542 assert_eq!(perform_cast_value(Data(Byte(Kilo)), Data(Byte(Kilo))), Some((Data(Byte(Kilo)), String::from("1.0"))));
1543 assert_eq!(perform_cast_value(Data(Byte(Kilo)), Data(Bit)), Some((Data(Bit), String::from("8000.0"))));
1544
1545 assert_eq!(perform_cast_value(Data(Bit), Data(Byte(Kilo))), Some((Data(Byte(Kilo)), String::from("0.000125"))));
1546 assert_eq!(perform_cast_value(Data(Bit), Data(Bit)), Some((Data(Bit), String::from("1.0"))));
1547 }
1548
1549 #[test]
1565 fn test_unit_values_are_added_by_meaning() {
1566 assert_eq!(perform_binary_ok(Value::calc_add, Plain, Plain), Some(Plain));
1567 assert_eq!(perform_binary_ok(Value::calc_add, Plain, Delta(Hour)), Some(Delta(Hour)));
1568 assert_eq!(perform_binary_ok(Value::calc_add, Plain, Time), Some(Time));
1569 assert_eq!(perform_binary_ok(Value::calc_add, Plain, Length(Mile)), Some(Length(Mile)));
1570 assert_eq!(perform_binary_ok(Value::calc_add, Plain, Area(Acre)), Some(Area(Acre)));
1571 assert_eq!(perform_binary_ok(Value::calc_add, Plain, Volume(Pint)), Some(Volume(Pint)));
1572 assert_eq!(perform_binary_ok(Value::calc_add, Plain, Speed(Light)), Some(Speed(Light)));
1573 assert_eq!(perform_binary_ok(Value::calc_add, Plain, Mass(Ounce)), Some(Mass(Ounce)));
1574 assert_eq!(perform_binary_ok(Value::calc_add, Plain, Temp(Rankine)), Some(Temp(Rankine)));
1575 assert_eq!(perform_binary_ok(Value::calc_add, Plain, Data(Bit)), Some(Data(Bit)));
1576
1577 assert_eq!(perform_binary_ok(Value::calc_add, Delta(Hour), Plain), Some(Delta(Hour)));
1578 assert_eq!(perform_binary_ok(Value::calc_add, Delta(Hour), Delta(Hour)), Some(Delta(Hour)));
1579 assert_eq!(perform_binary_ok(Value::calc_add, Delta(Hour), Time), Some(Time));
1580 assert_eq!(perform_binary_err(Value::calc_add, Delta(Hour), Length(Mile)), Some(BadCastOp(Length(Mile), Delta(Hour))));
1581 assert_eq!(perform_binary_err(Value::calc_add, Delta(Hour), Area(Acre)), Some(BadCastOp(Area(Acre), Delta(Hour))));
1582 assert_eq!(perform_binary_err(Value::calc_add, Delta(Hour), Volume(Pint)), Some(BadCastOp(Volume(Pint), Delta(Hour))));
1583 assert_eq!(perform_binary_err(Value::calc_add, Delta(Hour), Speed(Light)), Some(BadCastOp(Speed(Light), Delta(Hour))));
1584 assert_eq!(perform_binary_err(Value::calc_add, Delta(Hour), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Delta(Hour))));
1585 assert_eq!(perform_binary_err(Value::calc_add, Delta(Hour), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Delta(Hour))));
1586 assert_eq!(perform_binary_err(Value::calc_add, Delta(Hour), Data(Bit)), Some(BadCastOp(Data(Bit), Delta(Hour))));
1587
1588 assert_eq!(perform_binary_ok(Value::calc_add, Time, Plain), Some(Time));
1589 assert_eq!(perform_binary_ok(Value::calc_add, Time, Delta(Hour)), Some(Time));
1590 assert_eq!(perform_binary_err(Value::calc_add, Time, Time), Some(BadCastOp(Time, Time)));
1591 assert_eq!(perform_binary_err(Value::calc_add, Time, Length(Mile)), Some(BadCastOp(Length(Mile), Time)));
1592 assert_eq!(perform_binary_err(Value::calc_add, Time, Area(Acre)), Some(BadCastOp(Area(Acre), Time)));
1593 assert_eq!(perform_binary_err(Value::calc_add, Time, Volume(Pint)), Some(BadCastOp(Volume(Pint), Time)));
1594 assert_eq!(perform_binary_err(Value::calc_add, Time, Speed(Light)), Some(BadCastOp(Speed(Light), Time)));
1595 assert_eq!(perform_binary_err(Value::calc_add, Time, Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Time)));
1596 assert_eq!(perform_binary_err(Value::calc_add, Time, Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Time)));
1597 assert_eq!(perform_binary_err(Value::calc_add, Time, Data(Bit)), Some(BadCastOp(Data(Bit), Time)));
1598
1599 assert_eq!(perform_binary_ok(Value::calc_add, Length(Mile), Plain), Some(Length(Mile)));
1600 assert_eq!(perform_binary_err(Value::calc_add, Length(Mile), Delta(Hour)), Some(BadCastOp(Delta(Hour), Length(Mile))));
1601 assert_eq!(perform_binary_err(Value::calc_add, Length(Mile), Time), Some(BadCastOp(Time, Length(Mile))));
1602 assert_eq!(perform_binary_ok(Value::calc_add, Length(Mile), Length(Mile)), Some(Length(Mile)));
1603 assert_eq!(perform_binary_err(Value::calc_add, Length(Mile), Area(Acre)), Some(BadCastOp(Area(Acre), Length(Mile))));
1604 assert_eq!(perform_binary_err(Value::calc_add, Length(Mile), Volume(Pint)), Some(BadCastOp(Volume(Pint), Length(Mile))));
1605 assert_eq!(perform_binary_err(Value::calc_add, Length(Mile), Speed(Light)), Some(BadCastOp(Speed(Light), Length(Mile))));
1606 assert_eq!(perform_binary_err(Value::calc_add, Length(Mile), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Length(Mile))));
1607 assert_eq!(perform_binary_err(Value::calc_add, Length(Mile), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Length(Mile))));
1608 assert_eq!(perform_binary_err(Value::calc_add, Length(Mile), Data(Bit)), Some(BadCastOp(Data(Bit), Length(Mile))));
1609
1610 assert_eq!(perform_binary_ok(Value::calc_add, Area(Acre), Plain), Some(Area(Acre)));
1611 assert_eq!(perform_binary_err(Value::calc_add, Area(Acre), Delta(Hour)), Some(BadCastOp(Delta(Hour), Area(Acre))));
1612 assert_eq!(perform_binary_err(Value::calc_add, Area(Acre), Time), Some(BadCastOp(Time, Area(Acre))));
1613 assert_eq!(perform_binary_err(Value::calc_add, Area(Acre), Length(Mile)), Some(BadCastOp(Length(Mile), Area(Acre))));
1614 assert_eq!(perform_binary_ok(Value::calc_add, Area(Acre), Area(Acre)), Some(Area(Acre)));
1615 assert_eq!(perform_binary_err(Value::calc_add, Area(Acre), Volume(Pint)), Some(BadCastOp(Volume(Pint), Area(Acre))));
1616 assert_eq!(perform_binary_err(Value::calc_add, Area(Acre), Speed(Light)), Some(BadCastOp(Speed(Light), Area(Acre))));
1617 assert_eq!(perform_binary_err(Value::calc_add, Area(Acre), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Area(Acre))));
1618 assert_eq!(perform_binary_err(Value::calc_add, Area(Acre), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Area(Acre))));
1619 assert_eq!(perform_binary_err(Value::calc_add, Area(Acre), Data(Bit)), Some(BadCastOp(Data(Bit), Area(Acre))));
1620
1621 assert_eq!(perform_binary_ok(Value::calc_add, Volume(Pint), Plain), Some(Volume(Pint)));
1622 assert_eq!(perform_binary_err(Value::calc_add, Volume(Pint), Delta(Hour)), Some(BadCastOp(Delta(Hour), Volume(Pint))));
1623 assert_eq!(perform_binary_err(Value::calc_add, Volume(Pint), Time), Some(BadCastOp(Time, Volume(Pint))));
1624 assert_eq!(perform_binary_err(Value::calc_add, Volume(Pint), Length(Mile)), Some(BadCastOp(Length(Mile), Volume(Pint))));
1625 assert_eq!(perform_binary_err(Value::calc_add, Volume(Pint), Area(Acre)), Some(BadCastOp(Area(Acre), Volume(Pint))));
1626 assert_eq!(perform_binary_ok(Value::calc_add, Volume(Pint), Volume(Pint)), Some(Volume(Pint)));
1627 assert_eq!(perform_binary_err(Value::calc_add, Volume(Pint), Speed(Light)), Some(BadCastOp(Speed(Light), Volume(Pint))));
1628 assert_eq!(perform_binary_err(Value::calc_add, Volume(Pint), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Volume(Pint))));
1629 assert_eq!(perform_binary_err(Value::calc_add, Volume(Pint), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Volume(Pint))));
1630 assert_eq!(perform_binary_err(Value::calc_add, Volume(Pint), Data(Bit)), Some(BadCastOp(Data(Bit), Volume(Pint))));
1631
1632 assert_eq!(perform_binary_ok(Value::calc_add, Speed(Light), Plain), Some(Speed(Light)));
1633 assert_eq!(perform_binary_err(Value::calc_add, Speed(Light), Delta(Hour)), Some(BadCastOp(Delta(Hour), Speed(Light))));
1634 assert_eq!(perform_binary_err(Value::calc_add, Speed(Light), Time), Some(BadCastOp(Time, Speed(Light))));
1635 assert_eq!(perform_binary_err(Value::calc_add, Speed(Light), Length(Mile)), Some(BadCastOp(Length(Mile), Speed(Light))));
1636 assert_eq!(perform_binary_err(Value::calc_add, Speed(Light), Area(Acre)), Some(BadCastOp(Area(Acre), Speed(Light))));
1637 assert_eq!(perform_binary_err(Value::calc_add, Speed(Light), Volume(Pint)), Some(BadCastOp(Volume(Pint), Speed(Light))));
1638 assert_eq!(perform_binary_ok(Value::calc_add, Speed(Light), Speed(Light)), Some(Speed(Light)));
1639 assert_eq!(perform_binary_err(Value::calc_add, Speed(Light), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Speed(Light))));
1640 assert_eq!(perform_binary_err(Value::calc_add, Speed(Light), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Speed(Light))));
1641 assert_eq!(perform_binary_err(Value::calc_add, Speed(Light), Data(Bit)), Some(BadCastOp(Data(Bit), Speed(Light))));
1642
1643 assert_eq!(perform_binary_ok(Value::calc_add, Mass(Ounce), Plain), Some(Mass(Ounce)));
1644 assert_eq!(perform_binary_err(Value::calc_add, Mass(Ounce), Delta(Hour)), Some(BadCastOp(Delta(Hour), Mass(Ounce))));
1645 assert_eq!(perform_binary_err(Value::calc_add, Mass(Ounce), Time), Some(BadCastOp(Time, Mass(Ounce))));
1646 assert_eq!(perform_binary_err(Value::calc_add, Mass(Ounce), Length(Mile)), Some(BadCastOp(Length(Mile), Mass(Ounce))));
1647 assert_eq!(perform_binary_err(Value::calc_add, Mass(Ounce), Area(Acre)), Some(BadCastOp(Area(Acre), Mass(Ounce))));
1648 assert_eq!(perform_binary_err(Value::calc_add, Mass(Ounce), Volume(Pint)), Some(BadCastOp(Volume(Pint), Mass(Ounce))));
1649 assert_eq!(perform_binary_err(Value::calc_add, Mass(Ounce), Speed(Light)), Some(BadCastOp(Speed(Light), Mass(Ounce))));
1650 assert_eq!(perform_binary_ok(Value::calc_add, Mass(Ounce), Mass(Ounce)), Some(Mass(Ounce)));
1651 assert_eq!(perform_binary_err(Value::calc_add, Mass(Ounce), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Mass(Ounce))));
1652 assert_eq!(perform_binary_err(Value::calc_add, Mass(Ounce), Data(Bit)), Some(BadCastOp(Data(Bit), Mass(Ounce))));
1653
1654 assert_eq!(perform_binary_ok(Value::calc_add, Temp(Rankine), Plain), Some(Temp(Rankine)));
1655 assert_eq!(perform_binary_err(Value::calc_add, Temp(Rankine), Delta(Hour)), Some(BadCastOp(Delta(Hour), Temp(Rankine))));
1656 assert_eq!(perform_binary_err(Value::calc_add, Temp(Rankine), Time), Some(BadCastOp(Time, Temp(Rankine))));
1657 assert_eq!(perform_binary_err(Value::calc_add, Temp(Rankine), Length(Mile)), Some(BadCastOp(Length(Mile), Temp(Rankine))));
1658 assert_eq!(perform_binary_err(Value::calc_add, Temp(Rankine), Area(Acre)), Some(BadCastOp(Area(Acre), Temp(Rankine))));
1659 assert_eq!(perform_binary_err(Value::calc_add, Temp(Rankine), Volume(Pint)), Some(BadCastOp(Volume(Pint), Temp(Rankine))));
1660 assert_eq!(perform_binary_err(Value::calc_add, Temp(Rankine), Speed(Light)), Some(BadCastOp(Speed(Light), Temp(Rankine))));
1661 assert_eq!(perform_binary_err(Value::calc_add, Temp(Rankine), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Temp(Rankine))));
1662 assert_eq!(perform_binary_ok(Value::calc_add, Temp(Rankine), Temp(Rankine)), Some(Temp(Rankine)));
1663 assert_eq!(perform_binary_err(Value::calc_add, Temp(Rankine), Data(Bit)), Some(BadCastOp(Data(Bit), Temp(Rankine))));
1664
1665 assert_eq!(perform_binary_ok(Value::calc_add, Data(Bit), Plain), Some(Data(Bit)));
1666 assert_eq!(perform_binary_err(Value::calc_add, Data(Bit), Delta(Hour)), Some(BadCastOp(Delta(Hour), Data(Bit))));
1667 assert_eq!(perform_binary_err(Value::calc_add, Data(Bit), Time), Some(BadCastOp(Time, Data(Bit))));
1668 assert_eq!(perform_binary_err(Value::calc_add, Data(Bit), Length(Mile)), Some(BadCastOp(Length(Mile), Data(Bit))));
1669 assert_eq!(perform_binary_err(Value::calc_add, Data(Bit), Area(Acre)), Some(BadCastOp(Area(Acre), Data(Bit))));
1670 assert_eq!(perform_binary_err(Value::calc_add, Data(Bit), Volume(Pint)), Some(BadCastOp(Volume(Pint), Data(Bit))));
1671 assert_eq!(perform_binary_err(Value::calc_add, Data(Bit), Speed(Light)), Some(BadCastOp(Speed(Light), Data(Bit))));
1672 assert_eq!(perform_binary_err(Value::calc_add, Data(Bit), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Data(Bit))));
1673 assert_eq!(perform_binary_err(Value::calc_add, Data(Bit), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Data(Bit))));
1674 assert_eq!(perform_binary_ok(Value::calc_add, Data(Bit), Data(Bit)), Some(Data(Bit)));
1675 }
1676
1677 #[test]
1678 fn test_time_values_are_added_by_meaning() {
1679 assert_eq!(perform_binary_value(Value::calc_add, Delta(Second(Unit)), Delta(Second(Unit))), Some((Delta(Second(Unit)), String::from("2.0"))));
1680 assert_eq!(perform_binary_value(Value::calc_add, Delta(Second(Unit)), Delta(Minute)), Some((Delta(Second(Unit)), String::from("61.0"))));
1681 assert_eq!(perform_binary_value(Value::calc_add, Delta(Second(Unit)), Delta(HMS)), Some((Delta(Second(Unit)), String::from("2.0"))));
1682 assert_eq!(perform_binary_value(Value::calc_add, Delta(Second(Unit)), Time), Some((Time, String::from("1970-01-01T00:00:02.000Z"))));
1683
1684 assert_eq!(perform_binary_value(Value::calc_add, Delta(Minute), Delta(Second(Unit))), Some((Delta(Minute), String::from("1.016666667"))));
1685 assert_eq!(perform_binary_value(Value::calc_add, Delta(Minute), Delta(Minute)), Some((Delta(Minute), String::from("2.0"))));
1686 assert_eq!(perform_binary_value(Value::calc_add, Delta(Minute), Delta(HMS)), Some((Delta(Minute), String::from("1.016666667"))));
1687 assert_eq!(perform_binary_value(Value::calc_add, Delta(Minute), Time), Some((Time, String::from("1970-01-01T00:01:01.000Z"))));
1688
1689 assert_eq!(perform_binary_value(Value::calc_add, Delta(HMS), Delta(Second(Unit))), Some((Delta(HMS), String::from("02.000"))));
1690 assert_eq!(perform_binary_value(Value::calc_add, Delta(HMS), Delta(Minute)), Some((Delta(HMS), String::from("01:01.000"))));
1691 assert_eq!(perform_binary_value(Value::calc_add, Delta(HMS), Delta(HMS)), Some((Delta(HMS), String::from("02.000"))));
1692 assert_eq!(perform_binary_value(Value::calc_add, Delta(HMS), Time), Some((Time, String::from("1970-01-01T00:00:02.000Z"))));
1693
1694 assert_eq!(perform_binary_value(Value::calc_add, Time, Delta(Second(Unit))), Some((Time, String::from("1970-01-01T00:00:02.000Z"))));
1695 assert_eq!(perform_binary_value(Value::calc_add, Time, Delta(Minute)), Some((Time, String::from("1970-01-01T00:01:01.000Z"))));
1696 assert_eq!(perform_binary_value(Value::calc_add, Time, Delta(HMS)), Some((Time, String::from("1970-01-01T00:00:02.000Z"))));
1697 assert_eq!(perform_binary_err(Value::calc_add, Time, Time), Some(BadCastOp(Time, Time)));
1698 }
1699
1700 #[test]
1716 fn test_unit_values_are_subtracted_by_meaning() {
1717 assert_eq!(perform_binary_ok(Value::calc_sub, Plain, Plain), Some(Plain));
1718 assert_eq!(perform_binary_ok(Value::calc_sub, Plain, Delta(Hour)), Some(Delta(Hour)));
1719 assert_eq!(perform_binary_err(Value::calc_sub, Plain, Time), Some(BadCastOp(Time, Plain)));
1720 assert_eq!(perform_binary_ok(Value::calc_sub, Plain, Length(Mile)), Some(Length(Mile)));
1721 assert_eq!(perform_binary_ok(Value::calc_sub, Plain, Area(Acre)), Some(Area(Acre)));
1722 assert_eq!(perform_binary_ok(Value::calc_sub, Plain, Volume(Pint)), Some(Volume(Pint)));
1723 assert_eq!(perform_binary_ok(Value::calc_sub, Plain, Speed(Light)), Some(Speed(Light)));
1724 assert_eq!(perform_binary_ok(Value::calc_sub, Plain, Mass(Ounce)), Some(Mass(Ounce)));
1725 assert_eq!(perform_binary_ok(Value::calc_sub, Plain, Temp(Rankine)), Some(Temp(Rankine)));
1726 assert_eq!(perform_binary_ok(Value::calc_sub, Plain, Data(Bit)), Some(Data(Bit)));
1727
1728 assert_eq!(perform_binary_ok(Value::calc_sub, Delta(Hour), Plain), Some(Delta(Hour)));
1729 assert_eq!(perform_binary_ok(Value::calc_sub, Delta(Hour), Delta(Hour)), Some(Delta(Hour)));
1730 assert_eq!(perform_binary_err(Value::calc_sub, Delta(Hour), Time), Some(BadCastOp(Time, Delta(Hour))));
1731 assert_eq!(perform_binary_err(Value::calc_sub, Delta(Hour), Length(Mile)), Some(BadCastOp(Length(Mile), Delta(Hour))));
1732 assert_eq!(perform_binary_err(Value::calc_sub, Delta(Hour), Area(Acre)), Some(BadCastOp(Area(Acre), Delta(Hour))));
1733 assert_eq!(perform_binary_err(Value::calc_sub, Delta(Hour), Volume(Pint)), Some(BadCastOp(Volume(Pint), Delta(Hour))));
1734 assert_eq!(perform_binary_err(Value::calc_sub, Delta(Hour), Speed(Light)), Some(BadCastOp(Speed(Light), Delta(Hour))));
1735 assert_eq!(perform_binary_err(Value::calc_sub, Delta(Hour), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Delta(Hour))));
1736 assert_eq!(perform_binary_err(Value::calc_sub, Delta(Hour), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Delta(Hour))));
1737 assert_eq!(perform_binary_err(Value::calc_sub, Delta(Hour), Data(Bit)), Some(BadCastOp(Data(Bit), Delta(Hour))));
1738
1739 assert_eq!(perform_binary_ok(Value::calc_sub, Time, Plain), Some(Time));
1740 assert_eq!(perform_binary_ok(Value::calc_sub, Time, Delta(Hour)), Some(Time));
1741 assert_eq!(perform_binary_ok(Value::calc_sub, Time, Time), Some(Delta(HMS)));
1742 assert_eq!(perform_binary_err(Value::calc_sub, Time, Length(Mile)), Some(BadCastOp(Length(Mile), Time)));
1743 assert_eq!(perform_binary_err(Value::calc_sub, Time, Area(Acre)), Some(BadCastOp(Area(Acre), Time)));
1744 assert_eq!(perform_binary_err(Value::calc_sub, Time, Volume(Pint)), Some(BadCastOp(Volume(Pint), Time)));
1745 assert_eq!(perform_binary_err(Value::calc_sub, Time, Speed(Light)), Some(BadCastOp(Speed(Light), Time)));
1746 assert_eq!(perform_binary_err(Value::calc_sub, Time, Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Time)));
1747 assert_eq!(perform_binary_err(Value::calc_sub, Time, Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Time)));
1748 assert_eq!(perform_binary_err(Value::calc_sub, Time, Data(Bit)), Some(BadCastOp(Data(Bit), Time)));
1749
1750 assert_eq!(perform_binary_ok(Value::calc_sub, Length(Mile), Plain), Some(Length(Mile)));
1751 assert_eq!(perform_binary_err(Value::calc_sub, Length(Mile), Delta(Hour)), Some(BadCastOp(Delta(Hour), Length(Mile))));
1752 assert_eq!(perform_binary_err(Value::calc_sub, Length(Mile), Time), Some(BadCastOp(Time, Length(Mile))));
1753 assert_eq!(perform_binary_ok(Value::calc_sub, Length(Mile), Length(Mile)), Some(Length(Mile)));
1754 assert_eq!(perform_binary_err(Value::calc_sub, Length(Mile), Area(Acre)), Some(BadCastOp(Area(Acre), Length(Mile))));
1755 assert_eq!(perform_binary_err(Value::calc_sub, Length(Mile), Volume(Pint)), Some(BadCastOp(Volume(Pint), Length(Mile))));
1756 assert_eq!(perform_binary_err(Value::calc_sub, Length(Mile), Speed(Light)), Some(BadCastOp(Speed(Light), Length(Mile))));
1757 assert_eq!(perform_binary_err(Value::calc_sub, Length(Mile), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Length(Mile))));
1758 assert_eq!(perform_binary_err(Value::calc_sub, Length(Mile), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Length(Mile))));
1759 assert_eq!(perform_binary_err(Value::calc_sub, Length(Mile), Data(Bit)), Some(BadCastOp(Data(Bit), Length(Mile))));
1760
1761 assert_eq!(perform_binary_ok(Value::calc_sub, Area(Acre), Plain), Some(Area(Acre)));
1762 assert_eq!(perform_binary_err(Value::calc_sub, Area(Acre), Delta(Hour)), Some(BadCastOp(Delta(Hour), Area(Acre))));
1763 assert_eq!(perform_binary_err(Value::calc_sub, Area(Acre), Time), Some(BadCastOp(Time, Area(Acre))));
1764 assert_eq!(perform_binary_err(Value::calc_sub, Area(Acre), Length(Mile)), Some(BadCastOp(Length(Mile), Area(Acre))));
1765 assert_eq!(perform_binary_ok(Value::calc_sub, Area(Acre), Area(Acre)), Some(Area(Acre)));
1766 assert_eq!(perform_binary_err(Value::calc_sub, Area(Acre), Volume(Pint)), Some(BadCastOp(Volume(Pint), Area(Acre))));
1767 assert_eq!(perform_binary_err(Value::calc_sub, Area(Acre), Speed(Light)), Some(BadCastOp(Speed(Light), Area(Acre))));
1768 assert_eq!(perform_binary_err(Value::calc_sub, Area(Acre), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Area(Acre))));
1769 assert_eq!(perform_binary_err(Value::calc_sub, Area(Acre), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Area(Acre))));
1770 assert_eq!(perform_binary_err(Value::calc_sub, Area(Acre), Data(Bit)), Some(BadCastOp(Data(Bit), Area(Acre))));
1771
1772 assert_eq!(perform_binary_ok(Value::calc_sub, Volume(Pint), Plain), Some(Volume(Pint)));
1773 assert_eq!(perform_binary_err(Value::calc_sub, Volume(Pint), Delta(Hour)), Some(BadCastOp(Delta(Hour), Volume(Pint))));
1774 assert_eq!(perform_binary_err(Value::calc_sub, Volume(Pint), Time), Some(BadCastOp(Time, Volume(Pint))));
1775 assert_eq!(perform_binary_err(Value::calc_sub, Volume(Pint), Length(Mile)), Some(BadCastOp(Length(Mile), Volume(Pint))));
1776 assert_eq!(perform_binary_err(Value::calc_sub, Volume(Pint), Area(Acre)), Some(BadCastOp(Area(Acre), Volume(Pint))));
1777 assert_eq!(perform_binary_ok(Value::calc_sub, Volume(Pint), Volume(Pint)), Some(Volume(Pint)));
1778 assert_eq!(perform_binary_err(Value::calc_sub, Volume(Pint), Speed(Light)), Some(BadCastOp(Speed(Light), Volume(Pint))));
1779 assert_eq!(perform_binary_err(Value::calc_sub, Volume(Pint), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Volume(Pint))));
1780 assert_eq!(perform_binary_err(Value::calc_sub, Volume(Pint), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Volume(Pint))));
1781 assert_eq!(perform_binary_err(Value::calc_sub, Volume(Pint), Data(Bit)), Some(BadCastOp(Data(Bit), Volume(Pint))));
1782
1783 assert_eq!(perform_binary_ok(Value::calc_sub, Speed(Light), Plain), Some(Speed(Light)));
1784 assert_eq!(perform_binary_err(Value::calc_sub, Speed(Light), Delta(Hour)), Some(BadCastOp(Delta(Hour), Speed(Light))));
1785 assert_eq!(perform_binary_err(Value::calc_sub, Speed(Light), Time), Some(BadCastOp(Time, Speed(Light))));
1786 assert_eq!(perform_binary_err(Value::calc_sub, Speed(Light), Length(Mile)), Some(BadCastOp(Length(Mile), Speed(Light))));
1787 assert_eq!(perform_binary_err(Value::calc_sub, Speed(Light), Area(Acre)), Some(BadCastOp(Area(Acre), Speed(Light))));
1788 assert_eq!(perform_binary_err(Value::calc_sub, Speed(Light), Volume(Pint)), Some(BadCastOp(Volume(Pint), Speed(Light))));
1789 assert_eq!(perform_binary_ok(Value::calc_sub, Speed(Light), Speed(Light)), Some(Speed(Light)));
1790 assert_eq!(perform_binary_err(Value::calc_sub, Speed(Light), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Speed(Light))));
1791 assert_eq!(perform_binary_err(Value::calc_sub, Speed(Light), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Speed(Light))));
1792 assert_eq!(perform_binary_err(Value::calc_sub, Speed(Light), Data(Bit)), Some(BadCastOp(Data(Bit), Speed(Light))));
1793
1794 assert_eq!(perform_binary_ok(Value::calc_sub, Mass(Ounce), Plain), Some(Mass(Ounce)));
1795 assert_eq!(perform_binary_err(Value::calc_sub, Mass(Ounce), Delta(Hour)), Some(BadCastOp(Delta(Hour), Mass(Ounce))));
1796 assert_eq!(perform_binary_err(Value::calc_sub, Mass(Ounce), Time), Some(BadCastOp(Time, Mass(Ounce))));
1797 assert_eq!(perform_binary_err(Value::calc_sub, Mass(Ounce), Length(Mile)), Some(BadCastOp(Length(Mile), Mass(Ounce))));
1798 assert_eq!(perform_binary_err(Value::calc_sub, Mass(Ounce), Area(Acre)), Some(BadCastOp(Area(Acre), Mass(Ounce))));
1799 assert_eq!(perform_binary_err(Value::calc_sub, Mass(Ounce), Volume(Pint)), Some(BadCastOp(Volume(Pint), Mass(Ounce))));
1800 assert_eq!(perform_binary_err(Value::calc_sub, Mass(Ounce), Speed(Light)), Some(BadCastOp(Speed(Light), Mass(Ounce))));
1801 assert_eq!(perform_binary_ok(Value::calc_sub, Mass(Ounce), Mass(Ounce)), Some(Mass(Ounce)));
1802 assert_eq!(perform_binary_err(Value::calc_sub, Mass(Ounce), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Mass(Ounce))));
1803 assert_eq!(perform_binary_err(Value::calc_sub, Mass(Ounce), Data(Bit)), Some(BadCastOp(Data(Bit), Mass(Ounce))));
1804
1805 assert_eq!(perform_binary_ok(Value::calc_sub, Temp(Rankine), Plain), Some(Temp(Rankine)));
1806 assert_eq!(perform_binary_err(Value::calc_sub, Temp(Rankine), Delta(Hour)), Some(BadCastOp(Delta(Hour), Temp(Rankine))));
1807 assert_eq!(perform_binary_err(Value::calc_sub, Temp(Rankine), Time), Some(BadCastOp(Time, Temp(Rankine))));
1808 assert_eq!(perform_binary_err(Value::calc_sub, Temp(Rankine), Length(Mile)), Some(BadCastOp(Length(Mile), Temp(Rankine))));
1809 assert_eq!(perform_binary_err(Value::calc_sub, Temp(Rankine), Area(Acre)), Some(BadCastOp(Area(Acre), Temp(Rankine))));
1810 assert_eq!(perform_binary_err(Value::calc_sub, Temp(Rankine), Volume(Pint)), Some(BadCastOp(Volume(Pint), Temp(Rankine))));
1811 assert_eq!(perform_binary_err(Value::calc_sub, Temp(Rankine), Speed(Light)), Some(BadCastOp(Speed(Light), Temp(Rankine))));
1812 assert_eq!(perform_binary_err(Value::calc_sub, Temp(Rankine), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Temp(Rankine))));
1813 assert_eq!(perform_binary_ok(Value::calc_sub, Temp(Rankine), Temp(Rankine)), Some(Temp(Rankine)));
1814 assert_eq!(perform_binary_err(Value::calc_sub, Temp(Rankine), Data(Bit)), Some(BadCastOp(Data(Bit), Temp(Rankine))));
1815
1816 assert_eq!(perform_binary_ok(Value::calc_sub, Data(Bit), Plain), Some(Data(Bit)));
1817 assert_eq!(perform_binary_err(Value::calc_sub, Data(Bit), Delta(Hour)), Some(BadCastOp(Delta(Hour), Data(Bit))));
1818 assert_eq!(perform_binary_err(Value::calc_sub, Data(Bit), Time), Some(BadCastOp(Time, Data(Bit))));
1819 assert_eq!(perform_binary_err(Value::calc_sub, Data(Bit), Length(Mile)), Some(BadCastOp(Length(Mile), Data(Bit))));
1820 assert_eq!(perform_binary_err(Value::calc_sub, Data(Bit), Area(Acre)), Some(BadCastOp(Area(Acre), Data(Bit))));
1821 assert_eq!(perform_binary_err(Value::calc_sub, Data(Bit), Volume(Pint)), Some(BadCastOp(Volume(Pint), Data(Bit))));
1822 assert_eq!(perform_binary_err(Value::calc_sub, Data(Bit), Speed(Light)), Some(BadCastOp(Speed(Light), Data(Bit))));
1823 assert_eq!(perform_binary_err(Value::calc_sub, Data(Bit), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Data(Bit))));
1824 assert_eq!(perform_binary_err(Value::calc_sub, Data(Bit), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Data(Bit))));
1825 assert_eq!(perform_binary_ok(Value::calc_sub, Data(Bit), Data(Bit)), Some(Data(Bit)));
1826 }
1827
1828 #[test]
1829 fn test_time_values_are_subtracted_by_meaning() {
1830 assert_eq!(perform_binary_value(Value::calc_sub, Delta(Second(Unit)), Delta(Second(Unit))), Some((Delta(Second(Unit)), String::from("0.0"))));
1831 assert_eq!(perform_binary_value(Value::calc_sub, Delta(Second(Unit)), Delta(Minute)), Some((Delta(Second(Unit)), String::from("-59.0"))));
1832 assert_eq!(perform_binary_value(Value::calc_sub, Delta(Second(Unit)), Delta(HMS)), Some((Delta(Second(Unit)), String::from("0.0"))));
1833 assert_eq!(perform_binary_err(Value::calc_sub, Delta(Second(Unit)), Time), Some(BadCastOp(Time, Delta(Second(Unit)))));
1834
1835 assert_eq!(perform_binary_value(Value::calc_sub, Delta(Minute), Delta(Second(Unit))), Some((Delta(Minute), String::from("0.983333333"))));
1836 assert_eq!(perform_binary_value(Value::calc_sub, Delta(Minute), Delta(Minute)), Some((Delta(Minute), String::from("0.0"))));
1837 assert_eq!(perform_binary_value(Value::calc_sub, Delta(Minute), Delta(HMS)), Some((Delta(Minute), String::from("0.983333333"))));
1838 assert_eq!(perform_binary_err(Value::calc_sub, Delta(Minute), Time), Some(BadCastOp(Time, Delta(Minute))));
1839
1840 assert_eq!(perform_binary_value(Value::calc_sub, Delta(HMS), Delta(Second(Unit))), Some((Delta(HMS), String::from("00.000"))));
1841 assert_eq!(perform_binary_value(Value::calc_sub, Delta(HMS), Delta(Minute)), Some((Delta(HMS), String::from("-59.000"))));
1842 assert_eq!(perform_binary_value(Value::calc_sub, Delta(HMS), Delta(HMS)), Some((Delta(HMS), String::from("00.000"))));
1843 assert_eq!(perform_binary_err(Value::calc_sub, Delta(HMS), Time), Some(BadCastOp(Time, Delta(HMS))));
1844
1845 assert_eq!(perform_binary_value(Value::calc_sub, Time, Delta(Second(Unit))), Some((Time, String::from("1970-01-01T00:00:00.000Z"))));
1846 assert_eq!(perform_binary_value(Value::calc_sub, Time, Delta(Minute)), Some((Time, String::from("1969-12-31T23:59:01.000Z"))));
1847 assert_eq!(perform_binary_value(Value::calc_sub, Time, Delta(HMS)), Some((Time, String::from("1970-01-01T00:00:00.000Z"))));
1848 assert_eq!(perform_binary_value(Value::calc_sub, Time, Time), Some((Delta(HMS), String::from("00.000"))));
1849 }
1850
1851 #[test]
1867 fn test_unit_values_are_multiplied_by_meaning() {
1868 assert_eq!(perform_binary_ok(Value::calc_mul, Plain, Plain), Some(Plain));
1869 assert_eq!(perform_binary_ok(Value::calc_mul, Plain, Delta(Hour)), Some(Delta(Hour)));
1870 assert_eq!(perform_binary_err(Value::calc_mul, Plain, Time), Some(BadCastOp(Time, Plain)));
1871 assert_eq!(perform_binary_ok(Value::calc_mul, Plain, Length(Mile)), Some(Length(Mile)));
1872 assert_eq!(perform_binary_ok(Value::calc_mul, Plain, Area(Acre)), Some(Area(Acre)));
1873 assert_eq!(perform_binary_ok(Value::calc_mul, Plain, Volume(Pint)), Some(Volume(Pint)));
1874 assert_eq!(perform_binary_ok(Value::calc_mul, Plain, Speed(Light)), Some(Speed(Light)));
1875 assert_eq!(perform_binary_ok(Value::calc_mul, Plain, Mass(Ounce)), Some(Mass(Ounce)));
1876 assert_eq!(perform_binary_ok(Value::calc_mul, Plain, Temp(Rankine)), Some(Temp(Rankine)));
1877 assert_eq!(perform_binary_ok(Value::calc_mul, Plain, Data(Bit)), Some(Data(Bit)));
1878
1879 assert_eq!(perform_binary_ok(Value::calc_mul, Delta(Hour), Plain), Some(Delta(Hour)));
1880 assert_eq!(perform_binary_err(Value::calc_mul, Delta(Hour), Delta(Hour)), Some(BadCastOp(Delta(Hour), Delta(Hour))));
1881 assert_eq!(perform_binary_err(Value::calc_mul, Delta(Hour), Time), Some(BadCastOp(Time, Delta(Hour))));
1882 assert_eq!(perform_binary_err(Value::calc_mul, Delta(Hour), Length(Mile)), Some(BadCastOp(Length(Mile), Delta(Hour))));
1883 assert_eq!(perform_binary_err(Value::calc_mul, Delta(Hour), Area(Acre)), Some(BadCastOp(Area(Acre), Delta(Hour))));
1884 assert_eq!(perform_binary_err(Value::calc_mul, Delta(Hour), Volume(Pint)), Some(BadCastOp(Volume(Pint), Delta(Hour))));
1885 assert_eq!(perform_binary_ok(Value::calc_mul, Delta(Hour), Speed(Light)), Some(Length(Metre(Unit))));
1886 assert_eq!(perform_binary_err(Value::calc_mul, Delta(Hour), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Delta(Hour))));
1887 assert_eq!(perform_binary_err(Value::calc_mul, Delta(Hour), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Delta(Hour))));
1888 assert_eq!(perform_binary_err(Value::calc_mul, Delta(Hour), Data(Bit)), Some(BadCastOp(Data(Bit), Delta(Hour))));
1889
1890 assert_eq!(perform_binary_err(Value::calc_mul, Time, Plain), Some(BadCastOp(Plain, Time)));
1891 assert_eq!(perform_binary_err(Value::calc_mul, Time, Delta(Hour)), Some(BadCastOp(Delta(Hour), Time)));
1892 assert_eq!(perform_binary_err(Value::calc_mul, Time, Time), Some(BadCastOp(Time, Time)));
1893 assert_eq!(perform_binary_err(Value::calc_mul, Time, Length(Mile)), Some(BadCastOp(Length(Mile), Time)));
1894 assert_eq!(perform_binary_err(Value::calc_mul, Time, Area(Acre)), Some(BadCastOp(Area(Acre), Time)));
1895 assert_eq!(perform_binary_err(Value::calc_mul, Time, Volume(Pint)), Some(BadCastOp(Volume(Pint), Time)));
1896 assert_eq!(perform_binary_err(Value::calc_mul, Time, Speed(Light)), Some(BadCastOp(Speed(Light), Time)));
1897 assert_eq!(perform_binary_err(Value::calc_mul, Time, Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Time)));
1898 assert_eq!(perform_binary_err(Value::calc_mul, Time, Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Time)));
1899 assert_eq!(perform_binary_err(Value::calc_mul, Time, Data(Bit)), Some(BadCastOp(Data(Bit), Time)));
1900
1901 assert_eq!(perform_binary_ok(Value::calc_mul, Length(Mile), Plain), Some(Length(Mile)));
1902 assert_eq!(perform_binary_err(Value::calc_mul, Length(Mile), Delta(Hour)), Some(BadCastOp(Delta(Hour), Length(Mile))));
1903 assert_eq!(perform_binary_err(Value::calc_mul, Length(Mile), Time), Some(BadCastOp(Time, Length(Mile))));
1904 assert_eq!(perform_binary_ok(Value::calc_mul, Length(Mile), Length(Mile)), Some(Area(Square(Mile))));
1905 assert_eq!(perform_binary_ok(Value::calc_mul, Length(Mile), Area(Acre)), Some(Volume(Cubic(Mile))));
1906 assert_eq!(perform_binary_err(Value::calc_mul, Length(Mile), Volume(Pint)), Some(BadCastOp(Volume(Pint), Length(Mile))));
1907 assert_eq!(perform_binary_err(Value::calc_mul, Length(Mile), Speed(Light)), Some(BadCastOp(Speed(Light), Length(Mile))));
1908 assert_eq!(perform_binary_err(Value::calc_mul, Length(Mile), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Length(Mile))));
1909 assert_eq!(perform_binary_err(Value::calc_mul, Length(Mile), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Length(Mile))));
1910 assert_eq!(perform_binary_err(Value::calc_mul, Length(Mile), Data(Bit)), Some(BadCastOp(Data(Bit), Length(Mile))));
1911
1912 assert_eq!(perform_binary_ok(Value::calc_mul, Area(Acre), Plain), Some(Area(Acre)));
1913 assert_eq!(perform_binary_err(Value::calc_mul, Area(Acre), Delta(Hour)), Some(BadCastOp(Delta(Hour), Area(Acre))));
1914 assert_eq!(perform_binary_err(Value::calc_mul, Area(Acre), Time), Some(BadCastOp(Time, Area(Acre))));
1915 assert_eq!(perform_binary_ok(Value::calc_mul, Area(Acre), Length(Mile)), Some(Volume(Cubic(Metre(Unit)))));
1916 assert_eq!(perform_binary_err(Value::calc_mul, Area(Acre), Area(Acre)), Some(BadCastOp(Area(Acre), Area(Acre))));
1917 assert_eq!(perform_binary_err(Value::calc_mul, Area(Acre), Volume(Pint)), Some(BadCastOp(Volume(Pint), Area(Acre))));
1918 assert_eq!(perform_binary_err(Value::calc_mul, Area(Acre), Speed(Light)), Some(BadCastOp(Speed(Light), Area(Acre))));
1919 assert_eq!(perform_binary_err(Value::calc_mul, Area(Acre), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Area(Acre))));
1920 assert_eq!(perform_binary_err(Value::calc_mul, Area(Acre), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Area(Acre))));
1921 assert_eq!(perform_binary_err(Value::calc_mul, Area(Acre), Data(Bit)), Some(BadCastOp(Data(Bit), Area(Acre))));
1922
1923 assert_eq!(perform_binary_ok(Value::calc_mul, Volume(Pint), Plain), Some(Volume(Pint)));
1924 assert_eq!(perform_binary_err(Value::calc_mul, Volume(Pint), Delta(Hour)), Some(BadCastOp(Delta(Hour), Volume(Pint))));
1925 assert_eq!(perform_binary_err(Value::calc_mul, Volume(Pint), Time), Some(BadCastOp(Time, Volume(Pint))));
1926 assert_eq!(perform_binary_err(Value::calc_mul, Volume(Pint), Length(Mile)), Some(BadCastOp(Length(Mile), Volume(Pint))));
1927 assert_eq!(perform_binary_err(Value::calc_mul, Volume(Pint), Area(Acre)), Some(BadCastOp(Area(Acre), Volume(Pint))));
1928 assert_eq!(perform_binary_err(Value::calc_mul, Volume(Pint), Volume(Pint)), Some(BadCastOp(Volume(Pint), Volume(Pint))));
1929 assert_eq!(perform_binary_err(Value::calc_mul, Volume(Pint), Speed(Light)), Some(BadCastOp(Speed(Light), Volume(Pint))));
1930 assert_eq!(perform_binary_err(Value::calc_mul, Volume(Pint), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Volume(Pint))));
1931 assert_eq!(perform_binary_err(Value::calc_mul, Volume(Pint), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Volume(Pint))));
1932 assert_eq!(perform_binary_err(Value::calc_mul, Volume(Pint), Data(Bit)), Some(BadCastOp(Data(Bit), Volume(Pint))));
1933
1934 assert_eq!(perform_binary_ok(Value::calc_mul, Speed(Light), Plain), Some(Speed(Light)));
1935 assert_eq!(perform_binary_ok(Value::calc_mul, Speed(Light), Delta(Hour)), Some(Length(Metre(Unit))));
1936 assert_eq!(perform_binary_err(Value::calc_mul, Speed(Light), Time), Some(BadCastOp(Time, Speed(Light))));
1937 assert_eq!(perform_binary_err(Value::calc_mul, Speed(Light), Length(Mile)), Some(BadCastOp(Length(Mile), Speed(Light))));
1938 assert_eq!(perform_binary_err(Value::calc_mul, Speed(Light), Area(Acre)), Some(BadCastOp(Area(Acre), Speed(Light))));
1939 assert_eq!(perform_binary_err(Value::calc_mul, Speed(Light), Volume(Pint)), Some(BadCastOp(Volume(Pint), Speed(Light))));
1940 assert_eq!(perform_binary_err(Value::calc_mul, Speed(Light), Speed(Light)), Some(BadCastOp(Speed(Light), Speed(Light))));
1941 assert_eq!(perform_binary_err(Value::calc_mul, Speed(Light), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Speed(Light))));
1942 assert_eq!(perform_binary_err(Value::calc_mul, Speed(Light), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Speed(Light))));
1943 assert_eq!(perform_binary_err(Value::calc_mul, Speed(Light), Data(Bit)), Some(BadCastOp(Data(Bit), Speed(Light))));
1944
1945 assert_eq!(perform_binary_ok(Value::calc_mul, Mass(Ounce), Plain), Some(Mass(Ounce)));
1946 assert_eq!(perform_binary_err(Value::calc_mul, Mass(Ounce), Delta(Hour)), Some(BadCastOp(Delta(Hour), Mass(Ounce))));
1947 assert_eq!(perform_binary_err(Value::calc_mul, Mass(Ounce), Time), Some(BadCastOp(Time, Mass(Ounce))));
1948 assert_eq!(perform_binary_err(Value::calc_mul, Mass(Ounce), Length(Mile)), Some(BadCastOp(Length(Mile), Mass(Ounce))));
1949 assert_eq!(perform_binary_err(Value::calc_mul, Mass(Ounce), Area(Acre)), Some(BadCastOp(Area(Acre), Mass(Ounce))));
1950 assert_eq!(perform_binary_err(Value::calc_mul, Mass(Ounce), Volume(Pint)), Some(BadCastOp(Volume(Pint), Mass(Ounce))));
1951 assert_eq!(perform_binary_err(Value::calc_mul, Mass(Ounce), Speed(Light)), Some(BadCastOp(Speed(Light), Mass(Ounce))));
1952 assert_eq!(perform_binary_err(Value::calc_mul, Mass(Ounce), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Mass(Ounce))));
1953 assert_eq!(perform_binary_err(Value::calc_mul, Mass(Ounce), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Mass(Ounce))));
1954 assert_eq!(perform_binary_err(Value::calc_mul, Mass(Ounce), Data(Bit)), Some(BadCastOp(Data(Bit), Mass(Ounce))));
1955
1956 assert_eq!(perform_binary_ok(Value::calc_mul, Temp(Rankine), Plain), Some(Temp(Rankine)));
1957 assert_eq!(perform_binary_err(Value::calc_mul, Temp(Rankine), Delta(Hour)), Some(BadCastOp(Delta(Hour), Temp(Rankine))));
1958 assert_eq!(perform_binary_err(Value::calc_mul, Temp(Rankine), Time), Some(BadCastOp(Time, Temp(Rankine))));
1959 assert_eq!(perform_binary_err(Value::calc_mul, Temp(Rankine), Length(Mile)), Some(BadCastOp(Length(Mile), Temp(Rankine))));
1960 assert_eq!(perform_binary_err(Value::calc_mul, Temp(Rankine), Area(Acre)), Some(BadCastOp(Area(Acre), Temp(Rankine))));
1961 assert_eq!(perform_binary_err(Value::calc_mul, Temp(Rankine), Volume(Pint)), Some(BadCastOp(Volume(Pint), Temp(Rankine))));
1962 assert_eq!(perform_binary_err(Value::calc_mul, Temp(Rankine), Speed(Light)), Some(BadCastOp(Speed(Light), Temp(Rankine))));
1963 assert_eq!(perform_binary_err(Value::calc_mul, Temp(Rankine), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Temp(Rankine))));
1964 assert_eq!(perform_binary_err(Value::calc_mul, Temp(Rankine), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Temp(Rankine))));
1965 assert_eq!(perform_binary_err(Value::calc_mul, Temp(Rankine), Data(Bit)), Some(BadCastOp(Data(Bit), Temp(Rankine))));
1966
1967 assert_eq!(perform_binary_ok(Value::calc_mul, Data(Bit), Plain), Some(Data(Bit)));
1968 assert_eq!(perform_binary_err(Value::calc_mul, Data(Bit), Delta(Hour)), Some(BadCastOp(Delta(Hour), Data(Bit))));
1969 assert_eq!(perform_binary_err(Value::calc_mul, Data(Bit), Time), Some(BadCastOp(Time, Data(Bit))));
1970 assert_eq!(perform_binary_err(Value::calc_mul, Data(Bit), Length(Mile)), Some(BadCastOp(Length(Mile), Data(Bit))));
1971 assert_eq!(perform_binary_err(Value::calc_mul, Data(Bit), Area(Acre)), Some(BadCastOp(Area(Acre), Data(Bit))));
1972 assert_eq!(perform_binary_err(Value::calc_mul, Data(Bit), Volume(Pint)), Some(BadCastOp(Volume(Pint), Data(Bit))));
1973 assert_eq!(perform_binary_err(Value::calc_mul, Data(Bit), Speed(Light)), Some(BadCastOp(Speed(Light), Data(Bit))));
1974 assert_eq!(perform_binary_err(Value::calc_mul, Data(Bit), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Data(Bit))));
1975 assert_eq!(perform_binary_err(Value::calc_mul, Data(Bit), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Data(Bit))));
1976 assert_eq!(perform_binary_err(Value::calc_mul, Data(Bit), Data(Bit)), Some(BadCastOp(Data(Bit), Data(Bit))));
1977 }
1978
1979 #[test]
1980 fn test_length_values_are_multiplied_by_meaning() {
1981 assert_eq!(perform_binary_value(Value::calc_mul, Length(Metre(Kilo)), Length(Metre(Kilo))), Some((Area(Square(Metre(Kilo))), String::from("1.0"))));
1982 assert_eq!(perform_binary_value(Value::calc_mul, Length(Metre(Kilo)), Length(Mile)), Some((Area(Square(Metre(Kilo))), String::from("1.609344"))));
1983 assert_eq!(perform_binary_value(Value::calc_mul, Length(Metre(Kilo)), Area(Square(Metre(Kilo)))), Some((Volume(Cubic(Metre(Kilo))), String::from("1.0"))));
1984 assert_eq!(perform_binary_value(Value::calc_mul, Length(Metre(Kilo)), Area(Square(Mile))), Some((Volume(Cubic(Metre(Kilo))), String::from("2.58998811"))));
1985 assert_eq!(perform_binary_value(Value::calc_mul, Length(Metre(Kilo)), Area(Acre)), Some((Volume(Cubic(Metre(Kilo))), String::from("0.004046856"))));
1986
1987 assert_eq!(perform_binary_value(Value::calc_mul, Length(Mile), Length(Metre(Kilo))), Some((Area(Square(Mile)), String::from("0.621371192"))));
1988 assert_eq!(perform_binary_value(Value::calc_mul, Length(Mile), Length(Mile)), Some((Area(Square(Mile)), String::from("1.0"))));
1989 assert_eq!(perform_binary_value(Value::calc_mul, Length(Mile), Area(Square(Metre(Kilo)))), Some((Volume(Cubic(Mile)), String::from("0.386102159"))));
1990 assert_eq!(perform_binary_value(Value::calc_mul, Length(Mile), Area(Square(Mile))), Some((Volume(Cubic(Mile)), String::from("1.0"))));
1991 assert_eq!(perform_binary_value(Value::calc_mul, Length(Mile), Area(Acre)), Some((Volume(Cubic(Mile)), String::from("0.0015625"))));
1992
1993 assert_eq!(perform_binary_value(Value::calc_mul, Area(Square(Metre(Kilo))), Length(Metre(Kilo))), Some((Volume(Cubic(Metre(Kilo))), String::from("1.0"))));
1994 assert_eq!(perform_binary_value(Value::calc_mul, Area(Square(Metre(Kilo))), Length(Mile)), Some((Volume(Cubic(Metre(Kilo))), String::from("1.609344"))));
1995 assert_eq!(perform_binary_err(Value::calc_mul, Area(Square(Metre(Kilo))), Area(Square(Metre(Kilo)))), Some(BadCastOp(Area(Square(Metre(Kilo))), Area(Square(Metre(Kilo))))));
1996 assert_eq!(perform_binary_err(Value::calc_mul, Area(Square(Metre(Kilo))), Area(Square(Mile))), Some(BadCastOp(Area(Square(Mile)), Area(Square(Metre(Kilo))))));
1997 assert_eq!(perform_binary_err(Value::calc_mul, Area(Square(Metre(Kilo))), Area(Acre)), Some(BadCastOp(Area(Acre), Area(Square(Metre(Kilo))))));
1998
1999 assert_eq!(perform_binary_value(Value::calc_mul, Area(Square(Mile)), Length(Metre(Kilo))), Some((Volume(Cubic(Mile)), String::from("0.621371192"))));
2000 assert_eq!(perform_binary_value(Value::calc_mul, Area(Square(Mile)), Length(Mile)), Some((Volume(Cubic(Mile)), String::from("1.0"))));
2001 assert_eq!(perform_binary_err(Value::calc_mul, Area(Square(Mile)), Area(Square(Metre(Kilo)))), Some(BadCastOp(Area(Square(Metre(Kilo))), Area(Square(Mile)))));
2002 assert_eq!(perform_binary_err(Value::calc_mul, Area(Square(Mile)), Area(Square(Mile))), Some(BadCastOp(Area(Square(Mile)), Area(Square(Mile)))));
2003 assert_eq!(perform_binary_err(Value::calc_mul, Area(Square(Mile)), Area(Acre)), Some(BadCastOp(Area(Acre), Area(Square(Mile)))));
2004
2005 assert_eq!(perform_binary_value(Value::calc_mul, Area(Acre), Length(Metre(Kilo))), Some((Volume(Cubic(Metre(Unit))), String::from("4046856.4224"))));
2006 assert_eq!(perform_binary_value(Value::calc_mul, Area(Acre), Length(Mile)), Some((Volume(Cubic(Metre(Unit))), String::from("6512784.102250906"))));
2007 assert_eq!(perform_binary_err(Value::calc_mul, Area(Acre), Area(Square(Metre(Kilo)))), Some(BadCastOp(Area(Square(Metre(Kilo))), Area(Acre))));
2008 assert_eq!(perform_binary_err(Value::calc_mul, Area(Acre), Area(Square(Mile))), Some(BadCastOp(Area(Square(Mile)), Area(Acre))));
2009 assert_eq!(perform_binary_err(Value::calc_mul, Area(Acre), Area(Acre)), Some(BadCastOp(Area(Acre), Area(Acre))));
2010 }
2011
2012 #[test]
2013 fn test_speed_values_are_multiplied_by_meaning() {
2014 assert_eq!(perform_binary_err(Value::calc_mul, Delta(Hour), Delta(Hour)), Some(BadCastOp(Delta(Hour), Delta(Hour))));
2015 assert_eq!(perform_binary_value(Value::calc_mul, Delta(Hour), Speed(Ratio(Metre(Kilo), Second(Unit)))), Some((Length(Metre(Unit)), String::from("3600000.0"))));
2016 assert_eq!(perform_binary_value(Value::calc_mul, Delta(Hour), Speed(Ratio(Mile, Hour))), Some((Length(Metre(Unit)), String::from("1609.344"))));
2017 assert_eq!(perform_binary_value(Value::calc_mul, Delta(Hour), Speed(Light)), Some((Length(Metre(Unit)), String::from("1079252848800.0"))));
2018
2019 assert_eq!(perform_binary_value(Value::calc_mul, Speed(Ratio(Metre(Kilo), Second(Unit))), Delta(Hour)), Some((Length(Metre(Kilo)), String::from("3600.0"))));
2020 assert_eq!(perform_binary_err(Value::calc_mul, Speed(Ratio(Metre(Kilo), Second(Unit))), Speed(Ratio(Metre(Kilo), Second(Unit)))), Some(BadCastOp(Speed(Ratio(Metre(Kilo), Second(Unit))), Speed(Ratio(Metre(Kilo), Second(Unit))))));
2021 assert_eq!(perform_binary_err(Value::calc_mul, Speed(Ratio(Metre(Kilo), Second(Unit))), Speed(Ratio(Mile, Hour))), Some(BadCastOp(Speed(Ratio(Mile, Hour)), Speed(Ratio(Metre(Kilo), Second(Unit))))));
2022 assert_eq!(perform_binary_err(Value::calc_mul, Speed(Ratio(Metre(Kilo), Second(Unit))), Speed(Light)), Some(BadCastOp(Speed(Light), Speed(Ratio(Metre(Kilo), Second(Unit))))));
2023
2024 assert_eq!(perform_binary_value(Value::calc_mul, Speed(Ratio(Mile, Hour)), Delta(Hour)), Some((Length(Mile), String::from("1.0"))));
2025 assert_eq!(perform_binary_err(Value::calc_mul, Speed(Ratio(Mile, Hour)), Speed(Ratio(Metre(Kilo), Second(Unit)))), Some(BadCastOp(Speed(Ratio(Metre(Kilo), Second(Unit))), Speed(Ratio(Mile, Hour)))));
2026 assert_eq!(perform_binary_err(Value::calc_mul, Speed(Ratio(Mile, Hour)), Speed(Ratio(Mile, Hour))), Some(BadCastOp(Speed(Ratio(Mile, Hour)), Speed(Ratio(Mile, Hour)))));
2027 assert_eq!(perform_binary_err(Value::calc_mul, Speed(Ratio(Mile, Hour)), Speed(Light)), Some(BadCastOp(Speed(Light), Speed(Ratio(Mile, Hour)))));
2028
2029 assert_eq!(perform_binary_value(Value::calc_mul, Speed(Light), Delta(Hour)), Some((Length(Metre(Unit)), String::from("1079252848800.0"))));
2030 assert_eq!(perform_binary_err(Value::calc_mul, Speed(Light), Speed(Ratio(Metre(Kilo), Second(Unit)))), Some(BadCastOp(Speed(Ratio(Metre(Kilo), Second(Unit))), Speed(Light))));
2031 assert_eq!(perform_binary_err(Value::calc_mul, Speed(Light), Speed(Ratio(Mile, Hour))), Some(BadCastOp(Speed(Ratio(Mile, Hour)), Speed(Light))));
2032 assert_eq!(perform_binary_err(Value::calc_mul, Speed(Light), Speed(Light)), Some(BadCastOp(Speed(Light), Speed(Light))));
2033 }
2034
2035 #[test]
2051 fn test_unit_values_are_divided_by_meaning() {
2052 assert_eq!(perform_binary_ok(Value::calc_div, Plain, Plain), Some(Plain));
2053 assert_eq!(perform_binary_err(Value::calc_div, Plain, Delta(Hour)), Some(BadCastOp(Delta(Hour), Plain)));
2054 assert_eq!(perform_binary_err(Value::calc_div, Plain, Time), Some(BadCastOp(Time, Plain)));
2055 assert_eq!(perform_binary_err(Value::calc_div, Plain, Length(Mile)), Some(BadCastOp(Length(Mile), Plain)));
2056 assert_eq!(perform_binary_err(Value::calc_div, Plain, Area(Acre)), Some(BadCastOp(Area(Acre), Plain)));
2057 assert_eq!(perform_binary_err(Value::calc_div, Plain, Volume(Pint)), Some(BadCastOp(Volume(Pint), Plain)));
2058 assert_eq!(perform_binary_err(Value::calc_div, Plain, Speed(Light)), Some(BadCastOp(Speed(Light), Plain)));
2059 assert_eq!(perform_binary_err(Value::calc_div, Plain, Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Plain)));
2060 assert_eq!(perform_binary_err(Value::calc_div, Plain, Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Plain)));
2061 assert_eq!(perform_binary_err(Value::calc_div, Plain, Data(Bit)), Some(BadCastOp(Data(Bit), Plain)));
2062
2063 assert_eq!(perform_binary_ok(Value::calc_div, Delta(Hour), Plain), Some(Delta(Hour)));
2064 assert_eq!(perform_binary_ok(Value::calc_div, Delta(Hour), Delta(Hour)), Some(Plain));
2065 assert_eq!(perform_binary_err(Value::calc_div, Delta(Hour), Time), Some(BadCastOp(Time, Delta(Hour))));
2066 assert_eq!(perform_binary_err(Value::calc_div, Delta(Hour), Length(Mile)), Some(BadCastOp(Length(Mile), Delta(Hour))));
2067 assert_eq!(perform_binary_err(Value::calc_div, Delta(Hour), Area(Acre)), Some(BadCastOp(Area(Acre), Delta(Hour))));
2068 assert_eq!(perform_binary_err(Value::calc_div, Delta(Hour), Volume(Pint)), Some(BadCastOp(Volume(Pint), Delta(Hour))));
2069 assert_eq!(perform_binary_err(Value::calc_div, Delta(Hour), Speed(Light)), Some(BadCastOp(Speed(Light), Delta(Hour))));
2070 assert_eq!(perform_binary_err(Value::calc_div, Delta(Hour), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Delta(Hour))));
2071 assert_eq!(perform_binary_err(Value::calc_div, Delta(Hour), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Delta(Hour))));
2072 assert_eq!(perform_binary_err(Value::calc_div, Delta(Hour), Data(Bit)), Some(BadCastOp(Data(Bit), Delta(Hour))));
2073
2074 assert_eq!(perform_binary_err(Value::calc_div, Time, Plain), Some(BadCastOp(Plain, Time)));
2075 assert_eq!(perform_binary_err(Value::calc_div, Time, Delta(Hour)), Some(BadCastOp(Delta(Hour), Time)));
2076 assert_eq!(perform_binary_err(Value::calc_div, Time, Time), Some(BadCastOp(Time, Time)));
2077 assert_eq!(perform_binary_err(Value::calc_div, Time, Length(Mile)), Some(BadCastOp(Length(Mile), Time)));
2078 assert_eq!(perform_binary_err(Value::calc_div, Time, Area(Acre)), Some(BadCastOp(Area(Acre), Time)));
2079 assert_eq!(perform_binary_err(Value::calc_div, Time, Volume(Pint)), Some(BadCastOp(Volume(Pint), Time)));
2080 assert_eq!(perform_binary_err(Value::calc_div, Time, Speed(Light)), Some(BadCastOp(Speed(Light), Time)));
2081 assert_eq!(perform_binary_err(Value::calc_div, Time, Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Time)));
2082 assert_eq!(perform_binary_err(Value::calc_div, Time, Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Time)));
2083 assert_eq!(perform_binary_err(Value::calc_div, Time, Data(Bit)), Some(BadCastOp(Data(Bit), Time)));
2084
2085 assert_eq!(perform_binary_ok(Value::calc_div, Length(Mile), Plain), Some(Length(Mile)));
2086 assert_eq!(perform_binary_err(Value::calc_div, Length(Mile), Delta(Hour)), Some(BadCastOp(Delta(Hour), Length(Mile))));
2087 assert_eq!(perform_binary_err(Value::calc_div, Length(Mile), Time), Some(BadCastOp(Time, Length(Mile))));
2088 assert_eq!(perform_binary_ok(Value::calc_div, Length(Mile), Length(Mile)), Some(Plain));
2089 assert_eq!(perform_binary_err(Value::calc_div, Length(Mile), Area(Acre)), Some(BadCastOp(Area(Acre), Length(Mile))));
2090 assert_eq!(perform_binary_err(Value::calc_div, Length(Mile), Volume(Pint)), Some(BadCastOp(Volume(Pint), Length(Mile))));
2091 assert_eq!(perform_binary_ok(Value::calc_div, Length(Mile), Speed(Light)), Some(Delta(Second(Unit))));
2092 assert_eq!(perform_binary_err(Value::calc_div, Length(Mile), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Length(Mile))));
2093 assert_eq!(perform_binary_err(Value::calc_div, Length(Mile), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Length(Mile))));
2094 assert_eq!(perform_binary_err(Value::calc_div, Length(Mile), Data(Bit)), Some(BadCastOp(Data(Bit), Length(Mile))));
2095
2096 assert_eq!(perform_binary_ok(Value::calc_div, Area(Acre), Plain), Some(Area(Acre)));
2097 assert_eq!(perform_binary_err(Value::calc_div, Area(Acre), Delta(Hour)), Some(BadCastOp(Delta(Hour), Area(Acre))));
2098 assert_eq!(perform_binary_err(Value::calc_div, Area(Acre), Time), Some(BadCastOp(Time, Area(Acre))));
2099 assert_eq!(perform_binary_ok(Value::calc_div, Area(Acre), Length(Mile)), Some(Length(Metre(Unit))));
2100 assert_eq!(perform_binary_ok(Value::calc_div, Area(Acre), Area(Acre)), Some(Plain));
2101 assert_eq!(perform_binary_err(Value::calc_div, Area(Acre), Volume(Pint)), Some(BadCastOp(Volume(Pint), Area(Acre))));
2102 assert_eq!(perform_binary_err(Value::calc_div, Area(Acre), Speed(Light)), Some(BadCastOp(Speed(Light), Area(Acre))));
2103 assert_eq!(perform_binary_err(Value::calc_div, Area(Acre), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Area(Acre))));
2104 assert_eq!(perform_binary_err(Value::calc_div, Area(Acre), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Area(Acre))));
2105 assert_eq!(perform_binary_err(Value::calc_div, Area(Acre), Data(Bit)), Some(BadCastOp(Data(Bit), Area(Acre))));
2106
2107 assert_eq!(perform_binary_ok(Value::calc_div, Volume(Pint), Plain), Some(Volume(Pint)));
2108 assert_eq!(perform_binary_err(Value::calc_div, Volume(Pint), Delta(Hour)), Some(BadCastOp(Delta(Hour), Volume(Pint))));
2109 assert_eq!(perform_binary_err(Value::calc_div, Volume(Pint), Time), Some(BadCastOp(Time, Volume(Pint))));
2110 assert_eq!(perform_binary_ok(Value::calc_div, Volume(Pint), Length(Mile)), Some(Area(Square(Metre(Unit)))));
2111 assert_eq!(perform_binary_ok(Value::calc_div, Volume(Pint), Area(Acre)), Some(Length(Metre(Unit))));
2112 assert_eq!(perform_binary_ok(Value::calc_div, Volume(Pint), Volume(Pint)), Some(Plain));
2113 assert_eq!(perform_binary_err(Value::calc_div, Volume(Pint), Speed(Light)), Some(BadCastOp(Speed(Light), Volume(Pint))));
2114 assert_eq!(perform_binary_err(Value::calc_div, Volume(Pint), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Volume(Pint))));
2115 assert_eq!(perform_binary_err(Value::calc_div, Volume(Pint), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Volume(Pint))));
2116 assert_eq!(perform_binary_err(Value::calc_div, Volume(Pint), Data(Bit)), Some(BadCastOp(Data(Bit), Volume(Pint))));
2117
2118 assert_eq!(perform_binary_ok(Value::calc_div, Speed(Light), Plain), Some(Speed(Light)));
2119 assert_eq!(perform_binary_err(Value::calc_div, Speed(Light), Delta(Hour)), Some(BadCastOp(Delta(Hour), Speed(Light))));
2120 assert_eq!(perform_binary_err(Value::calc_div, Speed(Light), Time), Some(BadCastOp(Time, Speed(Light))));
2121 assert_eq!(perform_binary_err(Value::calc_div, Speed(Light), Length(Mile)), Some(BadCastOp(Length(Mile), Speed(Light))));
2122 assert_eq!(perform_binary_err(Value::calc_div, Speed(Light), Area(Acre)), Some(BadCastOp(Area(Acre), Speed(Light))));
2123 assert_eq!(perform_binary_err(Value::calc_div, Speed(Light), Volume(Pint)), Some(BadCastOp(Volume(Pint), Speed(Light))));
2124 assert_eq!(perform_binary_ok(Value::calc_div, Speed(Light), Speed(Light)), Some(Plain));
2125 assert_eq!(perform_binary_err(Value::calc_div, Speed(Light), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Speed(Light))));
2126 assert_eq!(perform_binary_err(Value::calc_div, Speed(Light), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Speed(Light))));
2127 assert_eq!(perform_binary_err(Value::calc_div, Speed(Light), Data(Bit)), Some(BadCastOp(Data(Bit), Speed(Light))));
2128
2129 assert_eq!(perform_binary_ok(Value::calc_div, Mass(Ounce), Plain), Some(Mass(Ounce)));
2130 assert_eq!(perform_binary_err(Value::calc_div, Mass(Ounce), Delta(Hour)), Some(BadCastOp(Delta(Hour), Mass(Ounce))));
2131 assert_eq!(perform_binary_err(Value::calc_div, Mass(Ounce), Time), Some(BadCastOp(Time, Mass(Ounce))));
2132 assert_eq!(perform_binary_err(Value::calc_div, Mass(Ounce), Length(Mile)), Some(BadCastOp(Length(Mile), Mass(Ounce))));
2133 assert_eq!(perform_binary_err(Value::calc_div, Mass(Ounce), Area(Acre)), Some(BadCastOp(Area(Acre), Mass(Ounce))));
2134 assert_eq!(perform_binary_err(Value::calc_div, Mass(Ounce), Volume(Pint)), Some(BadCastOp(Volume(Pint), Mass(Ounce))));
2135 assert_eq!(perform_binary_err(Value::calc_div, Mass(Ounce), Speed(Light)), Some(BadCastOp(Speed(Light), Mass(Ounce))));
2136 assert_eq!(perform_binary_ok(Value::calc_div, Mass(Ounce), Mass(Ounce)), Some(Plain));
2137 assert_eq!(perform_binary_err(Value::calc_div, Mass(Ounce), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Mass(Ounce))));
2138 assert_eq!(perform_binary_err(Value::calc_div, Mass(Ounce), Data(Bit)), Some(BadCastOp(Data(Bit), Mass(Ounce))));
2139
2140 assert_eq!(perform_binary_ok(Value::calc_div, Temp(Rankine), Plain), Some(Temp(Rankine)));
2141 assert_eq!(perform_binary_err(Value::calc_div, Temp(Rankine), Delta(Hour)), Some(BadCastOp(Delta(Hour), Temp(Rankine))));
2142 assert_eq!(perform_binary_err(Value::calc_div, Temp(Rankine), Time), Some(BadCastOp(Time, Temp(Rankine))));
2143 assert_eq!(perform_binary_err(Value::calc_div, Temp(Rankine), Length(Mile)), Some(BadCastOp(Length(Mile), Temp(Rankine))));
2144 assert_eq!(perform_binary_err(Value::calc_div, Temp(Rankine), Area(Acre)), Some(BadCastOp(Area(Acre), Temp(Rankine))));
2145 assert_eq!(perform_binary_err(Value::calc_div, Temp(Rankine), Volume(Pint)), Some(BadCastOp(Volume(Pint), Temp(Rankine))));
2146 assert_eq!(perform_binary_err(Value::calc_div, Temp(Rankine), Speed(Light)), Some(BadCastOp(Speed(Light), Temp(Rankine))));
2147 assert_eq!(perform_binary_err(Value::calc_div, Temp(Rankine), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Temp(Rankine))));
2148 assert_eq!(perform_binary_ok(Value::calc_div, Temp(Rankine), Temp(Rankine)), Some(Plain));
2149 assert_eq!(perform_binary_err(Value::calc_div, Temp(Rankine), Data(Bit)), Some(BadCastOp(Data(Bit), Temp(Rankine))));
2150
2151 assert_eq!(perform_binary_ok(Value::calc_div, Data(Bit), Plain), Some(Data(Bit)));
2152 assert_eq!(perform_binary_err(Value::calc_div, Data(Bit), Delta(Hour)), Some(BadCastOp(Delta(Hour), Data(Bit))));
2153 assert_eq!(perform_binary_err(Value::calc_div, Data(Bit), Time), Some(BadCastOp(Time, Data(Bit))));
2154 assert_eq!(perform_binary_err(Value::calc_div, Data(Bit), Length(Mile)), Some(BadCastOp(Length(Mile), Data(Bit))));
2155 assert_eq!(perform_binary_err(Value::calc_div, Data(Bit), Area(Acre)), Some(BadCastOp(Area(Acre), Data(Bit))));
2156 assert_eq!(perform_binary_err(Value::calc_div, Data(Bit), Volume(Pint)), Some(BadCastOp(Volume(Pint), Data(Bit))));
2157 assert_eq!(perform_binary_err(Value::calc_div, Data(Bit), Speed(Light)), Some(BadCastOp(Speed(Light), Data(Bit))));
2158 assert_eq!(perform_binary_err(Value::calc_div, Data(Bit), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Data(Bit))));
2159 assert_eq!(perform_binary_err(Value::calc_div, Data(Bit), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Data(Bit))));
2160 assert_eq!(perform_binary_ok(Value::calc_div, Data(Bit), Data(Bit)), Some(Plain));
2161 }
2162
2163 #[test]
2164 fn test_length_values_are_divided_by_meaning() {
2165 assert_eq!(perform_binary_value(Value::calc_div, Length(Metre(Kilo)), Length(Metre(Kilo))), Some((Plain, String::from("1.0"))));
2166 assert_eq!(perform_binary_value(Value::calc_div, Length(Metre(Kilo)), Length(Mile)), Some((Plain, String::from("0.621371192"))));
2167 assert_eq!(perform_binary_err(Value::calc_div, Length(Metre(Kilo)), Area(Square(Metre(Kilo)))), Some(BadCastOp(Area(Square(Metre(Kilo))), Length(Metre(Kilo)))));
2168 assert_eq!(perform_binary_err(Value::calc_div, Length(Metre(Kilo)), Area(Square(Mile))), Some(BadCastOp(Area(Square(Mile)), Length(Metre(Kilo)))));
2169 assert_eq!(perform_binary_err(Value::calc_div, Length(Metre(Kilo)), Area(Acre)), Some(BadCastOp(Area(Acre), Length(Metre(Kilo)))));
2170 assert_eq!(perform_binary_err(Value::calc_div, Length(Metre(Kilo)), Volume(Cubic(Metre(Kilo)))), Some(BadCastOp(Volume(Cubic(Metre(Kilo))), Length(Metre(Kilo)))));
2171 assert_eq!(perform_binary_err(Value::calc_div, Length(Metre(Kilo)), Volume(Cubic(Mile))), Some(BadCastOp(Volume(Cubic(Mile)), Length(Metre(Kilo)))));
2172 assert_eq!(perform_binary_err(Value::calc_div, Length(Metre(Kilo)), Volume(Litre(Milli))), Some(BadCastOp(Volume(Litre(Milli)), Length(Metre(Kilo)))));
2173 assert_eq!(perform_binary_err(Value::calc_div, Length(Metre(Kilo)), Volume(Pint)), Some(BadCastOp(Volume(Pint), Length(Metre(Kilo)))));
2174
2175 assert_eq!(perform_binary_value(Value::calc_div, Length(Mile), Length(Metre(Kilo))), Some((Plain, String::from("1.609344"))));
2176 assert_eq!(perform_binary_value(Value::calc_div, Length(Mile), Length(Mile)), Some((Plain, String::from("1.0"))));
2177 assert_eq!(perform_binary_err(Value::calc_div, Length(Mile), Area(Square(Metre(Kilo)))), Some(BadCastOp(Area(Square(Metre(Kilo))), Length(Mile))));
2178 assert_eq!(perform_binary_err(Value::calc_div, Length(Mile), Area(Square(Mile))), Some(BadCastOp(Area(Square(Mile)), Length(Mile))));
2179 assert_eq!(perform_binary_err(Value::calc_div, Length(Mile), Area(Acre)), Some(BadCastOp(Area(Acre), Length(Mile))));
2180 assert_eq!(perform_binary_err(Value::calc_div, Length(Mile), Volume(Cubic(Metre(Kilo)))), Some(BadCastOp(Volume(Cubic(Metre(Kilo))), Length(Mile))));
2181 assert_eq!(perform_binary_err(Value::calc_div, Length(Mile), Volume(Cubic(Mile))), Some(BadCastOp(Volume(Cubic(Mile)), Length(Mile))));
2182 assert_eq!(perform_binary_err(Value::calc_div, Length(Mile), Volume(Litre(Milli))), Some(BadCastOp(Volume(Litre(Milli)), Length(Mile))));
2183 assert_eq!(perform_binary_err(Value::calc_div, Length(Mile), Volume(Pint)), Some(BadCastOp(Volume(Pint), Length(Mile))));
2184
2185 assert_eq!(perform_binary_value(Value::calc_div, Area(Square(Metre(Kilo))), Length(Metre(Kilo))), Some((Length(Metre(Kilo)), String::from("1.0"))));
2186 assert_eq!(perform_binary_value(Value::calc_div, Area(Square(Metre(Kilo))), Length(Mile)), Some((Length(Metre(Kilo)), String::from("0.621371192"))));
2187 assert_eq!(perform_binary_value(Value::calc_div, Area(Square(Metre(Kilo))), Area(Square(Metre(Kilo)))), Some((Plain, String::from("1.0"))));
2188 assert_eq!(perform_binary_value(Value::calc_div, Area(Square(Metre(Kilo))), Area(Square(Mile))), Some((Plain, String::from("0.386102159"))));
2189 assert_eq!(perform_binary_value(Value::calc_div, Area(Square(Metre(Kilo))), Area(Acre)), Some((Plain, String::from("247.105381467"))));
2190 assert_eq!(perform_binary_err(Value::calc_div, Area(Square(Metre(Kilo))), Volume(Cubic(Metre(Kilo)))), Some(BadCastOp(Volume(Cubic(Metre(Kilo))), Area(Square(Metre(Kilo))))));
2191 assert_eq!(perform_binary_err(Value::calc_div, Area(Square(Metre(Kilo))), Volume(Cubic(Mile))), Some(BadCastOp(Volume(Cubic(Mile)), Area(Square(Metre(Kilo))))));
2192 assert_eq!(perform_binary_err(Value::calc_div, Area(Square(Metre(Kilo))), Volume(Litre(Milli))), Some(BadCastOp(Volume(Litre(Milli)), Area(Square(Metre(Kilo))))));
2193 assert_eq!(perform_binary_err(Value::calc_div, Area(Square(Metre(Kilo))), Volume(Pint)), Some(BadCastOp(Volume(Pint), Area(Square(Metre(Kilo))))));
2194
2195 assert_eq!(perform_binary_value(Value::calc_div, Area(Square(Mile)), Length(Metre(Kilo))), Some((Length(Mile), String::from("1.609344"))));
2196 assert_eq!(perform_binary_value(Value::calc_div, Area(Square(Mile)), Length(Mile)), Some((Length(Mile), String::from("1.0"))));
2197 assert_eq!(perform_binary_value(Value::calc_div, Area(Square(Mile)), Area(Square(Metre(Kilo)))), Some((Plain, String::from("2.58998811"))));
2198 assert_eq!(perform_binary_value(Value::calc_div, Area(Square(Mile)), Area(Square(Mile))), Some((Plain, String::from("1.0"))));
2199 assert_eq!(perform_binary_value(Value::calc_div, Area(Square(Mile)), Area(Acre)), Some((Plain, String::from("640.0"))));
2200 assert_eq!(perform_binary_err(Value::calc_div, Area(Square(Mile)), Volume(Cubic(Metre(Kilo)))), Some(BadCastOp(Volume(Cubic(Metre(Kilo))), Area(Square(Mile)))));
2201 assert_eq!(perform_binary_err(Value::calc_div, Area(Square(Mile)), Volume(Cubic(Mile))), Some(BadCastOp(Volume(Cubic(Mile)), Area(Square(Mile)))));
2202 assert_eq!(perform_binary_err(Value::calc_div, Area(Square(Mile)), Volume(Litre(Milli))), Some(BadCastOp(Volume(Litre(Milli)), Area(Square(Mile)))));
2203 assert_eq!(perform_binary_err(Value::calc_div, Area(Square(Mile)), Volume(Pint)), Some(BadCastOp(Volume(Pint), Area(Square(Mile)))));
2204
2205 assert_eq!(perform_binary_value(Value::calc_div, Area(Acre), Length(Metre(Kilo))), Some((Length(Metre(Unit)), String::from("4.046856422"))));
2206 assert_eq!(perform_binary_value(Value::calc_div, Area(Acre), Length(Mile)), Some((Length(Metre(Unit)), String::from("2.5146"))));
2207 assert_eq!(perform_binary_value(Value::calc_div, Area(Acre), Area(Square(Metre(Kilo)))), Some((Plain, String::from("0.004046856"))));
2208 assert_eq!(perform_binary_value(Value::calc_div, Area(Acre), Area(Square(Mile))), Some((Plain, String::from("0.0015625"))));
2209 assert_eq!(perform_binary_value(Value::calc_div, Area(Acre), Area(Acre)), Some((Plain, String::from("1.0"))));
2210 assert_eq!(perform_binary_err(Value::calc_div, Area(Acre), Volume(Cubic(Metre(Kilo)))), Some(BadCastOp(Volume(Cubic(Metre(Kilo))), Area(Acre))));
2211 assert_eq!(perform_binary_err(Value::calc_div, Area(Acre), Volume(Cubic(Mile))), Some(BadCastOp(Volume(Cubic(Mile)), Area(Acre))));
2212 assert_eq!(perform_binary_err(Value::calc_div, Area(Acre), Volume(Litre(Milli))), Some(BadCastOp(Volume(Litre(Milli)), Area(Acre))));
2213 assert_eq!(perform_binary_err(Value::calc_div, Area(Acre), Volume(Pint)), Some(BadCastOp(Volume(Pint), Area(Acre))));
2214
2215 assert_eq!(perform_binary_value(Value::calc_div, Volume(Cubic(Metre(Kilo))), Length(Metre(Kilo))), Some((Area(Square(Metre(Kilo))), String::from("1.0"))));
2216 assert_eq!(perform_binary_value(Value::calc_div, Volume(Cubic(Metre(Kilo))), Length(Mile)), Some((Area(Square(Metre(Kilo))), String::from("0.621371192"))));
2217 assert_eq!(perform_binary_value(Value::calc_div, Volume(Cubic(Metre(Kilo))), Area(Square(Metre(Kilo)))), Some((Length(Metre(Kilo)), String::from("1.0"))));
2218 assert_eq!(perform_binary_value(Value::calc_div, Volume(Cubic(Metre(Kilo))), Area(Square(Mile))), Some((Length(Metre(Kilo)), String::from("0.386102159"))));
2219 assert_eq!(perform_binary_value(Value::calc_div, Volume(Cubic(Metre(Kilo))), Area(Acre)), Some((Length(Metre(Kilo)), String::from("247.105381467"))));
2220 assert_eq!(perform_binary_value(Value::calc_div, Volume(Cubic(Metre(Kilo))), Volume(Cubic(Metre(Kilo)))), Some((Plain, String::from("1.0"))));
2221 assert_eq!(perform_binary_value(Value::calc_div, Volume(Cubic(Metre(Kilo))), Volume(Cubic(Mile))), Some((Plain, String::from("0.239912759"))));
2222 assert_eq!(perform_binary_value(Value::calc_div, Volume(Cubic(Metre(Kilo))), Volume(Litre(Milli))), Some((Plain, String::from("1000000000000000.0"))));
2223 assert_eq!(perform_binary_value(Value::calc_div, Volume(Cubic(Metre(Kilo))), Volume(Pint)), Some((Plain, String::from("1759753986392.702300218"))));
2224
2225 assert_eq!(perform_binary_value(Value::calc_div, Volume(Cubic(Mile)), Length(Metre(Kilo))), Some((Area(Square(Mile)), String::from("1.609344"))));
2226 assert_eq!(perform_binary_value(Value::calc_div, Volume(Cubic(Mile)), Length(Mile)), Some((Area(Square(Mile)), String::from("1.0"))));
2227 assert_eq!(perform_binary_value(Value::calc_div, Volume(Cubic(Mile)), Area(Square(Metre(Kilo)))), Some((Length(Mile), String::from("2.58998811"))));
2228 assert_eq!(perform_binary_value(Value::calc_div, Volume(Cubic(Mile)), Area(Square(Mile))), Some((Length(Mile), String::from("1.0"))));
2229 assert_eq!(perform_binary_value(Value::calc_div, Volume(Cubic(Mile)), Area(Acre)), Some((Length(Mile), String::from("640.0"))));
2230 assert_eq!(perform_binary_value(Value::calc_div, Volume(Cubic(Mile)), Volume(Cubic(Metre(Kilo)))), Some((Plain, String::from("4.168181825"))));
2231 assert_eq!(perform_binary_value(Value::calc_div, Volume(Cubic(Mile)), Volume(Cubic(Mile))), Some((Plain, String::from("1.0"))));
2232 assert_eq!(perform_binary_value(Value::calc_div, Volume(Cubic(Mile)), Volume(Litre(Milli))), Some((Plain, String::from("4168181825440579.584"))));
2233 assert_eq!(perform_binary_value(Value::calc_div, Volume(Cubic(Mile)), Volume(Pint)), Some((Plain, String::from("7334974583328.670719673"))));
2234
2235 assert_eq!(perform_binary_value(Value::calc_div, Volume(Litre(Milli)), Length(Metre(Kilo))), Some((Area(Square(Metre(Unit))), String::from("0.000000001"))));
2236 assert_eq!(perform_binary_value(Value::calc_div, Volume(Litre(Milli)), Length(Mile)), Some((Area(Square(Metre(Unit))), String::from("0.000000001"))));
2237 assert_eq!(perform_binary_value(Value::calc_div, Volume(Litre(Milli)), Area(Square(Metre(Kilo)))), Some((Length(Metre(Unit)), String::from("0.0"))));
2238 assert_eq!(perform_binary_value(Value::calc_div, Volume(Litre(Milli)), Area(Square(Mile))), Some((Length(Metre(Unit)), String::from("0.0"))));
2239 assert_eq!(perform_binary_value(Value::calc_div, Volume(Litre(Milli)), Area(Acre)), Some((Length(Metre(Unit)), String::from("0.0"))));
2240 assert_eq!(perform_binary_value(Value::calc_div, Volume(Litre(Milli)), Volume(Cubic(Metre(Kilo)))), Some((Plain, String::from("0.0"))));
2241 assert_eq!(perform_binary_value(Value::calc_div, Volume(Litre(Milli)), Volume(Cubic(Mile))), Some((Plain, String::from("0.0"))));
2242 assert_eq!(perform_binary_value(Value::calc_div, Volume(Litre(Milli)), Volume(Litre(Milli))), Some((Plain, String::from("1.0"))));
2243 assert_eq!(perform_binary_value(Value::calc_div, Volume(Litre(Milli)), Volume(Pint)), Some((Plain, String::from("0.001759754"))));
2244
2245 assert_eq!(perform_binary_value(Value::calc_div, Volume(Pint), Length(Metre(Kilo))), Some((Area(Square(Metre(Unit))), String::from("0.000000568"))));
2246 assert_eq!(perform_binary_value(Value::calc_div, Volume(Pint), Length(Mile)), Some((Area(Square(Metre(Unit))), String::from("0.000000353"))));
2247 assert_eq!(perform_binary_value(Value::calc_div, Volume(Pint), Area(Square(Metre(Kilo)))), Some((Length(Metre(Unit)), String::from("0.000000001"))));
2248 assert_eq!(perform_binary_value(Value::calc_div, Volume(Pint), Area(Square(Mile))), Some((Length(Metre(Unit)), String::from("0.0"))));
2249 assert_eq!(perform_binary_value(Value::calc_div, Volume(Pint), Area(Acre)), Some((Length(Metre(Unit)), String::from("0.00000014"))));
2250 assert_eq!(perform_binary_value(Value::calc_div, Volume(Pint), Volume(Cubic(Metre(Kilo)))), Some((Plain, String::from("0.0"))));
2251 assert_eq!(perform_binary_value(Value::calc_div, Volume(Pint), Volume(Cubic(Mile))), Some((Plain, String::from("0.0"))));
2252 assert_eq!(perform_binary_value(Value::calc_div, Volume(Pint), Volume(Litre(Milli))), Some((Plain, String::from("568.26125"))));
2253 assert_eq!(perform_binary_value(Value::calc_div, Volume(Pint), Volume(Pint)), Some((Plain, String::from("1.0"))));
2254 }
2255
2256 #[test]
2257 fn test_unit_values_are_remaindered_by_meaning() {
2258 assert_eq!(perform_binary_ok(Value::calc_mod, Plain, Plain), Some(Plain));
2259 assert_eq!(perform_binary_err(Value::calc_mod, Plain, Delta(Hour)), Some(BadCastOp(Delta(Hour), Plain)));
2260 assert_eq!(perform_binary_err(Value::calc_mod, Plain, Time), Some(BadCastOp(Time, Plain)));
2261 assert_eq!(perform_binary_err(Value::calc_mod, Plain, Length(Mile)), Some(BadCastOp(Length(Mile), Plain)));
2262 assert_eq!(perform_binary_err(Value::calc_mod, Plain, Area(Acre)), Some(BadCastOp(Area(Acre), Plain)));
2263 assert_eq!(perform_binary_err(Value::calc_mod, Plain, Volume(Pint)), Some(BadCastOp(Volume(Pint), Plain)));
2264 assert_eq!(perform_binary_err(Value::calc_mod, Plain, Speed(Light)), Some(BadCastOp(Speed(Light), Plain)));
2265 assert_eq!(perform_binary_err(Value::calc_mod, Plain, Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Plain)));
2266 assert_eq!(perform_binary_err(Value::calc_mod, Plain, Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Plain)));
2267 assert_eq!(perform_binary_err(Value::calc_mod, Plain, Data(Bit)), Some(BadCastOp(Data(Bit), Plain)));
2268
2269 assert_eq!(perform_binary_ok(Value::calc_mod, Delta(Hour), Plain), Some(Delta(Hour)));
2270 assert_eq!(perform_binary_ok(Value::calc_mod, Delta(Hour), Delta(Hour)), Some(Plain));
2271 assert_eq!(perform_binary_err(Value::calc_mod, Delta(Hour), Time), Some(BadCastOp(Time, Delta(Hour))));
2272 assert_eq!(perform_binary_err(Value::calc_mod, Delta(Hour), Length(Mile)), Some(BadCastOp(Length(Mile), Delta(Hour))));
2273 assert_eq!(perform_binary_err(Value::calc_mod, Delta(Hour), Area(Acre)), Some(BadCastOp(Area(Acre), Delta(Hour))));
2274 assert_eq!(perform_binary_err(Value::calc_mod, Delta(Hour), Volume(Pint)), Some(BadCastOp(Volume(Pint), Delta(Hour))));
2275 assert_eq!(perform_binary_err(Value::calc_mod, Delta(Hour), Speed(Light)), Some(BadCastOp(Speed(Light), Delta(Hour))));
2276 assert_eq!(perform_binary_err(Value::calc_mod, Delta(Hour), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Delta(Hour))));
2277 assert_eq!(perform_binary_err(Value::calc_mod, Delta(Hour), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Delta(Hour))));
2278 assert_eq!(perform_binary_err(Value::calc_mod, Delta(Hour), Data(Bit)), Some(BadCastOp(Data(Bit), Delta(Hour))));
2279
2280 assert_eq!(perform_binary_err(Value::calc_mod, Time, Plain), Some(BadCastOp(Plain, Time)));
2281 assert_eq!(perform_binary_err(Value::calc_mod, Time, Delta(Hour)), Some(BadCastOp(Delta(Hour), Time)));
2282 assert_eq!(perform_binary_err(Value::calc_mod, Time, Time), Some(BadCastOp(Time, Time)));
2283 assert_eq!(perform_binary_err(Value::calc_mod, Time, Length(Mile)), Some(BadCastOp(Length(Mile), Time)));
2284 assert_eq!(perform_binary_err(Value::calc_mod, Time, Area(Acre)), Some(BadCastOp(Area(Acre), Time)));
2285 assert_eq!(perform_binary_err(Value::calc_mod, Time, Volume(Pint)), Some(BadCastOp(Volume(Pint), Time)));
2286 assert_eq!(perform_binary_err(Value::calc_mod, Time, Speed(Light)), Some(BadCastOp(Speed(Light), Time)));
2287 assert_eq!(perform_binary_err(Value::calc_mod, Time, Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Time)));
2288 assert_eq!(perform_binary_err(Value::calc_mod, Time, Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Time)));
2289 assert_eq!(perform_binary_err(Value::calc_mod, Time, Data(Bit)), Some(BadCastOp(Data(Bit), Time)));
2290
2291 assert_eq!(perform_binary_ok(Value::calc_mod, Length(Mile), Plain), Some(Length(Mile)));
2292 assert_eq!(perform_binary_err(Value::calc_mod, Length(Mile), Delta(Hour)), Some(BadCastOp(Delta(Hour), Length(Mile))));
2293 assert_eq!(perform_binary_err(Value::calc_mod, Length(Mile), Time), Some(BadCastOp(Time, Length(Mile))));
2294 assert_eq!(perform_binary_ok(Value::calc_mod, Length(Mile), Length(Mile)), Some(Plain));
2295 assert_eq!(perform_binary_err(Value::calc_mod, Length(Mile), Area(Acre)), Some(BadCastOp(Area(Acre), Length(Mile))));
2296 assert_eq!(perform_binary_err(Value::calc_mod, Length(Mile), Volume(Pint)), Some(BadCastOp(Volume(Pint), Length(Mile))));
2297 assert_eq!(perform_binary_ok(Value::calc_mod, Length(Mile), Speed(Light)), Some(Delta(Second(Unit))));
2298 assert_eq!(perform_binary_err(Value::calc_mod, Length(Mile), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Length(Mile))));
2299 assert_eq!(perform_binary_err(Value::calc_mod, Length(Mile), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Length(Mile))));
2300 assert_eq!(perform_binary_err(Value::calc_mod, Length(Mile), Data(Bit)), Some(BadCastOp(Data(Bit), Length(Mile))));
2301
2302 assert_eq!(perform_binary_ok(Value::calc_mod, Area(Acre), Plain), Some(Area(Acre)));
2303 assert_eq!(perform_binary_err(Value::calc_mod, Area(Acre), Delta(Hour)), Some(BadCastOp(Delta(Hour), Area(Acre))));
2304 assert_eq!(perform_binary_err(Value::calc_mod, Area(Acre), Time), Some(BadCastOp(Time, Area(Acre))));
2305 assert_eq!(perform_binary_ok(Value::calc_mod, Area(Acre), Length(Mile)), Some(Length(Metre(Unit))));
2306 assert_eq!(perform_binary_ok(Value::calc_mod, Area(Acre), Area(Acre)), Some(Plain));
2307 assert_eq!(perform_binary_err(Value::calc_mod, Area(Acre), Volume(Pint)), Some(BadCastOp(Volume(Pint), Area(Acre))));
2308 assert_eq!(perform_binary_err(Value::calc_mod, Area(Acre), Speed(Light)), Some(BadCastOp(Speed(Light), Area(Acre))));
2309 assert_eq!(perform_binary_err(Value::calc_mod, Area(Acre), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Area(Acre))));
2310 assert_eq!(perform_binary_err(Value::calc_mod, Area(Acre), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Area(Acre))));
2311 assert_eq!(perform_binary_err(Value::calc_mod, Area(Acre), Data(Bit)), Some(BadCastOp(Data(Bit), Area(Acre))));
2312
2313 assert_eq!(perform_binary_ok(Value::calc_mod, Volume(Pint), Plain), Some(Volume(Pint)));
2314 assert_eq!(perform_binary_err(Value::calc_mod, Volume(Pint), Delta(Hour)), Some(BadCastOp(Delta(Hour), Volume(Pint))));
2315 assert_eq!(perform_binary_err(Value::calc_mod, Volume(Pint), Time), Some(BadCastOp(Time, Volume(Pint))));
2316 assert_eq!(perform_binary_ok(Value::calc_mod, Volume(Pint), Length(Mile)), Some(Area(Square(Metre(Unit)))));
2317 assert_eq!(perform_binary_ok(Value::calc_mod, Volume(Pint), Area(Acre)), Some(Length(Metre(Unit))));
2318 assert_eq!(perform_binary_ok(Value::calc_mod, Volume(Pint), Volume(Pint)), Some(Plain));
2319 assert_eq!(perform_binary_err(Value::calc_mod, Volume(Pint), Speed(Light)), Some(BadCastOp(Speed(Light), Volume(Pint))));
2320 assert_eq!(perform_binary_err(Value::calc_mod, Volume(Pint), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Volume(Pint))));
2321 assert_eq!(perform_binary_err(Value::calc_mod, Volume(Pint), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Volume(Pint))));
2322 assert_eq!(perform_binary_err(Value::calc_mod, Volume(Pint), Data(Bit)), Some(BadCastOp(Data(Bit), Volume(Pint))));
2323
2324 assert_eq!(perform_binary_ok(Value::calc_mod, Speed(Light), Plain), Some(Speed(Light)));
2325 assert_eq!(perform_binary_err(Value::calc_mod, Speed(Light), Delta(Hour)), Some(BadCastOp(Delta(Hour), Speed(Light))));
2326 assert_eq!(perform_binary_err(Value::calc_mod, Speed(Light), Time), Some(BadCastOp(Time, Speed(Light))));
2327 assert_eq!(perform_binary_err(Value::calc_mod, Speed(Light), Length(Mile)), Some(BadCastOp(Length(Mile), Speed(Light))));
2328 assert_eq!(perform_binary_err(Value::calc_mod, Speed(Light), Area(Acre)), Some(BadCastOp(Area(Acre), Speed(Light))));
2329 assert_eq!(perform_binary_err(Value::calc_mod, Speed(Light), Volume(Pint)), Some(BadCastOp(Volume(Pint), Speed(Light))));
2330 assert_eq!(perform_binary_ok(Value::calc_mod, Speed(Light), Speed(Light)), Some(Plain));
2331 assert_eq!(perform_binary_err(Value::calc_mod, Speed(Light), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Speed(Light))));
2332 assert_eq!(perform_binary_err(Value::calc_mod, Speed(Light), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Speed(Light))));
2333 assert_eq!(perform_binary_err(Value::calc_mod, Speed(Light), Data(Bit)), Some(BadCastOp(Data(Bit), Speed(Light))));
2334
2335 assert_eq!(perform_binary_ok(Value::calc_mod, Mass(Ounce), Plain), Some(Mass(Ounce)));
2336 assert_eq!(perform_binary_err(Value::calc_mod, Mass(Ounce), Delta(Hour)), Some(BadCastOp(Delta(Hour), Mass(Ounce))));
2337 assert_eq!(perform_binary_err(Value::calc_mod, Mass(Ounce), Time), Some(BadCastOp(Time, Mass(Ounce))));
2338 assert_eq!(perform_binary_err(Value::calc_mod, Mass(Ounce), Length(Mile)), Some(BadCastOp(Length(Mile), Mass(Ounce))));
2339 assert_eq!(perform_binary_err(Value::calc_mod, Mass(Ounce), Area(Acre)), Some(BadCastOp(Area(Acre), Mass(Ounce))));
2340 assert_eq!(perform_binary_err(Value::calc_mod, Mass(Ounce), Volume(Pint)), Some(BadCastOp(Volume(Pint), Mass(Ounce))));
2341 assert_eq!(perform_binary_err(Value::calc_mod, Mass(Ounce), Speed(Light)), Some(BadCastOp(Speed(Light), Mass(Ounce))));
2342 assert_eq!(perform_binary_ok(Value::calc_mod, Mass(Ounce), Mass(Ounce)), Some(Plain));
2343 assert_eq!(perform_binary_err(Value::calc_mod, Mass(Ounce), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Mass(Ounce))));
2344 assert_eq!(perform_binary_err(Value::calc_mod, Mass(Ounce), Data(Bit)), Some(BadCastOp(Data(Bit), Mass(Ounce))));
2345
2346 assert_eq!(perform_binary_ok(Value::calc_mod, Temp(Rankine), Plain), Some(Temp(Rankine)));
2347 assert_eq!(perform_binary_err(Value::calc_mod, Temp(Rankine), Delta(Hour)), Some(BadCastOp(Delta(Hour), Temp(Rankine))));
2348 assert_eq!(perform_binary_err(Value::calc_mod, Temp(Rankine), Time), Some(BadCastOp(Time, Temp(Rankine))));
2349 assert_eq!(perform_binary_err(Value::calc_mod, Temp(Rankine), Length(Mile)), Some(BadCastOp(Length(Mile), Temp(Rankine))));
2350 assert_eq!(perform_binary_err(Value::calc_mod, Temp(Rankine), Area(Acre)), Some(BadCastOp(Area(Acre), Temp(Rankine))));
2351 assert_eq!(perform_binary_err(Value::calc_mod, Temp(Rankine), Volume(Pint)), Some(BadCastOp(Volume(Pint), Temp(Rankine))));
2352 assert_eq!(perform_binary_err(Value::calc_mod, Temp(Rankine), Speed(Light)), Some(BadCastOp(Speed(Light), Temp(Rankine))));
2353 assert_eq!(perform_binary_err(Value::calc_mod, Temp(Rankine), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Temp(Rankine))));
2354 assert_eq!(perform_binary_ok(Value::calc_mod, Temp(Rankine), Temp(Rankine)), Some(Plain));
2355 assert_eq!(perform_binary_err(Value::calc_mod, Temp(Rankine), Data(Bit)), Some(BadCastOp(Data(Bit), Temp(Rankine))));
2356
2357 assert_eq!(perform_binary_ok(Value::calc_mod, Data(Bit), Plain), Some(Data(Bit)));
2358 assert_eq!(perform_binary_err(Value::calc_mod, Data(Bit), Delta(Hour)), Some(BadCastOp(Delta(Hour), Data(Bit))));
2359 assert_eq!(perform_binary_err(Value::calc_mod, Data(Bit), Time), Some(BadCastOp(Time, Data(Bit))));
2360 assert_eq!(perform_binary_err(Value::calc_mod, Data(Bit), Length(Mile)), Some(BadCastOp(Length(Mile), Data(Bit))));
2361 assert_eq!(perform_binary_err(Value::calc_mod, Data(Bit), Area(Acre)), Some(BadCastOp(Area(Acre), Data(Bit))));
2362 assert_eq!(perform_binary_err(Value::calc_mod, Data(Bit), Volume(Pint)), Some(BadCastOp(Volume(Pint), Data(Bit))));
2363 assert_eq!(perform_binary_err(Value::calc_mod, Data(Bit), Speed(Light)), Some(BadCastOp(Speed(Light), Data(Bit))));
2364 assert_eq!(perform_binary_err(Value::calc_mod, Data(Bit), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Data(Bit))));
2365 assert_eq!(perform_binary_err(Value::calc_mod, Data(Bit), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Data(Bit))));
2366 assert_eq!(perform_binary_ok(Value::calc_mod, Data(Bit), Data(Bit)), Some(Plain));
2367 }
2368
2369 #[test]
2370 fn test_length_values_are_remaindered_by_meaning() {
2371 assert_eq!(perform_binary_value(Value::calc_mod, Length(Metre(Kilo)), Length(Metre(Kilo))), Some((Plain, String::from("0.0"))));
2372 assert_eq!(perform_binary_value(Value::calc_mod, Length(Metre(Kilo)), Length(Mile)), Some((Plain, String::from("1000.0"))));
2373 assert_eq!(perform_binary_err(Value::calc_mod, Length(Metre(Kilo)), Area(Square(Metre(Kilo)))), Some(BadCastOp(Area(Square(Metre(Kilo))), Length(Metre(Kilo)))));
2374 assert_eq!(perform_binary_err(Value::calc_mod, Length(Metre(Kilo)), Area(Square(Mile))), Some(BadCastOp(Area(Square(Mile)), Length(Metre(Kilo)))));
2375 assert_eq!(perform_binary_err(Value::calc_mod, Length(Metre(Kilo)), Area(Acre)), Some(BadCastOp(Area(Acre), Length(Metre(Kilo)))));
2376 assert_eq!(perform_binary_err(Value::calc_mod, Length(Metre(Kilo)), Volume(Cubic(Metre(Kilo)))), Some(BadCastOp(Volume(Cubic(Metre(Kilo))), Length(Metre(Kilo)))));
2377 assert_eq!(perform_binary_err(Value::calc_mod, Length(Metre(Kilo)), Volume(Cubic(Mile))), Some(BadCastOp(Volume(Cubic(Mile)), Length(Metre(Kilo)))));
2378 assert_eq!(perform_binary_err(Value::calc_mod, Length(Metre(Kilo)), Volume(Litre(Milli))), Some(BadCastOp(Volume(Litre(Milli)), Length(Metre(Kilo)))));
2379 assert_eq!(perform_binary_err(Value::calc_mod, Length(Metre(Kilo)), Volume(Pint)), Some(BadCastOp(Volume(Pint), Length(Metre(Kilo)))));
2380
2381 assert_eq!(perform_binary_value(Value::calc_mod, Length(Mile), Length(Metre(Kilo))), Some((Plain, String::from("609.344"))));
2382 assert_eq!(perform_binary_value(Value::calc_mod, Length(Mile), Length(Mile)), Some((Plain, String::from("0.0"))));
2383 assert_eq!(perform_binary_err(Value::calc_mod, Length(Mile), Area(Square(Metre(Kilo)))), Some(BadCastOp(Area(Square(Metre(Kilo))), Length(Mile))));
2384 assert_eq!(perform_binary_err(Value::calc_mod, Length(Mile), Area(Square(Mile))), Some(BadCastOp(Area(Square(Mile)), Length(Mile))));
2385 assert_eq!(perform_binary_err(Value::calc_mod, Length(Mile), Area(Acre)), Some(BadCastOp(Area(Acre), Length(Mile))));
2386 assert_eq!(perform_binary_err(Value::calc_mod, Length(Mile), Volume(Cubic(Metre(Kilo)))), Some(BadCastOp(Volume(Cubic(Metre(Kilo))), Length(Mile))));
2387 assert_eq!(perform_binary_err(Value::calc_mod, Length(Mile), Volume(Cubic(Mile))), Some(BadCastOp(Volume(Cubic(Mile)), Length(Mile))));
2388 assert_eq!(perform_binary_err(Value::calc_mod, Length(Mile), Volume(Litre(Milli))), Some(BadCastOp(Volume(Litre(Milli)), Length(Mile))));
2389 assert_eq!(perform_binary_err(Value::calc_mod, Length(Mile), Volume(Pint)), Some(BadCastOp(Volume(Pint), Length(Mile))));
2390
2391 assert_eq!(perform_binary_value(Value::calc_mod, Area(Square(Metre(Kilo))), Length(Metre(Kilo))), Some((Length(Metre(Kilo)), String::from("0.0"))));
2392 assert_eq!(perform_binary_value(Value::calc_mod, Area(Square(Metre(Kilo))), Length(Mile)), Some((Length(Metre(Kilo)), String::from("0.597376"))));
2393 assert_eq!(perform_binary_value(Value::calc_mod, Area(Square(Metre(Kilo))), Area(Square(Metre(Kilo)))), Some((Plain, String::from("0.0"))));
2394 assert_eq!(perform_binary_value(Value::calc_mod, Area(Square(Metre(Kilo))), Area(Square(Mile))), Some((Plain, String::from("1000000.0"))));
2395 assert_eq!(perform_binary_value(Value::calc_mod, Area(Square(Metre(Kilo))), Area(Acre)), Some((Plain, String::from("426.4636672"))));
2396 assert_eq!(perform_binary_err(Value::calc_mod, Area(Square(Metre(Kilo))), Volume(Cubic(Metre(Kilo)))), Some(BadCastOp(Volume(Cubic(Metre(Kilo))), Area(Square(Metre(Kilo))))));
2397 assert_eq!(perform_binary_err(Value::calc_mod, Area(Square(Metre(Kilo))), Volume(Cubic(Mile))), Some(BadCastOp(Volume(Cubic(Mile)), Area(Square(Metre(Kilo))))));
2398 assert_eq!(perform_binary_err(Value::calc_mod, Area(Square(Metre(Kilo))), Volume(Litre(Milli))), Some(BadCastOp(Volume(Litre(Milli)), Area(Square(Metre(Kilo))))));
2399 assert_eq!(perform_binary_err(Value::calc_mod, Area(Square(Metre(Kilo))), Volume(Pint)), Some(BadCastOp(Volume(Pint), Area(Square(Metre(Kilo))))));
2400
2401 assert_eq!(perform_binary_value(Value::calc_mod, Area(Square(Mile)), Length(Metre(Kilo))), Some((Length(Mile), String::from("0.613983298"))));
2402 assert_eq!(perform_binary_value(Value::calc_mod, Area(Square(Mile)), Length(Mile)), Some((Length(Mile), String::from("0.344"))));
2403 assert_eq!(perform_binary_value(Value::calc_mod, Area(Square(Mile)), Area(Square(Metre(Kilo)))), Some((Plain, String::from("589988.110336"))));
2404 assert_eq!(perform_binary_value(Value::calc_mod, Area(Square(Mile)), Area(Square(Mile))), Some((Plain, String::from("0.0"))));
2405 assert_eq!(perform_binary_value(Value::calc_mod, Area(Square(Mile)), Area(Acre)), Some((Plain, String::from("0.0"))));
2406 assert_eq!(perform_binary_err(Value::calc_mod, Area(Square(Mile)), Volume(Cubic(Metre(Kilo)))), Some(BadCastOp(Volume(Cubic(Metre(Kilo))), Area(Square(Mile)))));
2407 assert_eq!(perform_binary_err(Value::calc_mod, Area(Square(Mile)), Volume(Cubic(Mile))), Some(BadCastOp(Volume(Cubic(Mile)), Area(Square(Mile)))));
2408 assert_eq!(perform_binary_err(Value::calc_mod, Area(Square(Mile)), Volume(Litre(Milli))), Some(BadCastOp(Volume(Litre(Milli)), Area(Square(Mile)))));
2409 assert_eq!(perform_binary_err(Value::calc_mod, Area(Square(Mile)), Volume(Pint)), Some(BadCastOp(Volume(Pint), Area(Square(Mile)))));
2410
2411 assert_eq!(perform_binary_value(Value::calc_mod, Area(Acre), Length(Metre(Kilo))), Some((Length(Metre(Unit)), String::from("46.8564224"))));
2412 assert_eq!(perform_binary_value(Value::calc_mod, Area(Acre), Length(Mile)), Some((Length(Metre(Unit)), String::from("828.1684224"))));
2413 assert_eq!(perform_binary_value(Value::calc_mod, Area(Acre), Area(Square(Metre(Kilo)))), Some((Plain, String::from("4046.8564224"))));
2414 assert_eq!(perform_binary_value(Value::calc_mod, Area(Acre), Area(Square(Mile))), Some((Plain, String::from("4046.8564224"))));
2415 assert_eq!(perform_binary_value(Value::calc_mod, Area(Acre), Area(Acre)), Some((Plain, String::from("0.0"))));
2416 assert_eq!(perform_binary_err(Value::calc_mod, Area(Acre), Volume(Cubic(Metre(Kilo)))), Some(BadCastOp(Volume(Cubic(Metre(Kilo))), Area(Acre))));
2417 assert_eq!(perform_binary_err(Value::calc_mod, Area(Acre), Volume(Cubic(Mile))), Some(BadCastOp(Volume(Cubic(Mile)), Area(Acre))));
2418 assert_eq!(perform_binary_err(Value::calc_mod, Area(Acre), Volume(Litre(Milli))), Some(BadCastOp(Volume(Litre(Milli)), Area(Acre))));
2419 assert_eq!(perform_binary_err(Value::calc_mod, Area(Acre), Volume(Pint)), Some(BadCastOp(Volume(Pint), Area(Acre))));
2420
2421 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Cubic(Metre(Kilo))), Length(Metre(Kilo))), Some((Area(Square(Metre(Kilo))), String::from("0.0"))));
2422 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Cubic(Metre(Kilo))), Length(Mile)), Some((Area(Square(Metre(Kilo))), String::from("0.000309376"))));
2423 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Cubic(Metre(Kilo))), Area(Square(Metre(Kilo)))), Some((Length(Metre(Kilo)), String::from("0.0"))));
2424 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Cubic(Metre(Kilo))), Area(Square(Mile))), Some((Length(Metre(Kilo)), String::from("264.589410304"))));
2425 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Cubic(Metre(Kilo))), Area(Acre)), Some((Length(Metre(Kilo)), String::from("1.543742848"))));
2426 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Cubic(Metre(Kilo))), Volume(Cubic(Metre(Kilo)))), Some((Plain, String::from("0.0"))));
2427 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Cubic(Metre(Kilo))), Volume(Cubic(Mile))), Some((Plain, String::from("1000000000.0"))));
2428 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Cubic(Metre(Kilo))), Volume(Litre(Milli))), Some((Plain, String::from("0.0"))));
2429 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Cubic(Metre(Kilo))), Volume(Pint)), Some((Plain, String::from("0.00039909"))));
2430
2431 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Cubic(Mile)), Length(Metre(Kilo))), Some((Area(Square(Mile)), String::from("0.000318704"))));
2432 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Cubic(Mile)), Length(Mile)), Some((Area(Square(Mile)), String::from("0.00006856"))));
2433 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Cubic(Mile)), Area(Square(Metre(Kilo)))), Some((Length(Mile), String::from("112.981090792"))));
2434 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Cubic(Mile)), Area(Square(Mile))), Some((Length(Mile), String::from("553.614336"))));
2435 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Cubic(Mile)), Area(Acre)), Some((Length(Mile), String::from("0.402336"))));
2436 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Cubic(Mile)), Volume(Cubic(Metre(Kilo)))), Some((Plain, String::from("168181825.440579584"))));
2437 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Cubic(Mile)), Volume(Cubic(Mile))), Some((Plain, String::from("0.0"))));
2438 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Cubic(Mile)), Volume(Litre(Milli))), Some((Plain, String::from("0.000000584"))));
2439 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Cubic(Mile)), Volume(Pint)), Some((Plain, String::from("0.000381144"))));
2440
2441 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Litre(Milli)), Length(Metre(Kilo))), Some((Area(Square(Metre(Unit))), String::from("0.000001"))));
2442 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Litre(Milli)), Length(Mile)), Some((Area(Square(Metre(Unit))), String::from("0.000001"))));
2443 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Litre(Milli)), Area(Square(Metre(Kilo)))), Some((Length(Metre(Unit)), String::from("0.000001"))));
2444 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Litre(Milli)), Area(Square(Mile))), Some((Length(Metre(Unit)), String::from("0.000001"))));
2445 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Litre(Milli)), Area(Acre)), Some((Length(Metre(Unit)), String::from("0.000001"))));
2446 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Litre(Milli)), Volume(Cubic(Metre(Kilo)))), Some((Plain, String::from("0.000001"))));
2447 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Litre(Milli)), Volume(Cubic(Mile))), Some((Plain, String::from("0.000001"))));
2448 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Litre(Milli)), Volume(Litre(Milli))), Some((Plain, String::from("0.0"))));
2449 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Litre(Milli)), Volume(Pint)), Some((Plain, String::from("0.000001"))));
2450
2451 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Pint), Length(Metre(Kilo))), Some((Area(Square(Metre(Unit))), String::from("0.000568261"))));
2452 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Pint), Length(Mile)), Some((Area(Square(Metre(Unit))), String::from("0.000568261"))));
2453 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Pint), Area(Square(Metre(Kilo)))), Some((Length(Metre(Unit)), String::from("0.000568261"))));
2454 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Pint), Area(Square(Mile))), Some((Length(Metre(Unit)), String::from("0.000568261"))));
2455 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Pint), Area(Acre)), Some((Length(Metre(Unit)), String::from("0.000568261"))));
2456 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Pint), Volume(Cubic(Metre(Kilo)))), Some((Plain, String::from("0.000568261"))));
2457 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Pint), Volume(Cubic(Mile))), Some((Plain, String::from("0.000568261"))));
2458 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Pint), Volume(Litre(Milli))), Some((Plain, String::from("0.000000261"))));
2459 assert_eq!(perform_binary_value(Value::calc_mod, Volume(Pint), Volume(Pint)), Some((Plain, String::from("0.0"))));
2460 }
2461
2462 #[test]
2470 fn test_unit_values_are_negated_by_meaning() {
2471 assert_eq!(perform_unary_ok(Value::calc_neg, Plain), Some(Plain));
2472 assert_eq!(perform_unary_ok(Value::calc_neg, Delta(Hour)), Some(Delta(Hour)));
2473 assert_eq!(perform_unary_err(Value::calc_neg, Time), Some(BadCastOp(Time, Time)));
2474 assert_eq!(perform_unary_ok(Value::calc_neg, Length(Mile)), Some(Length(Mile)));
2475 assert_eq!(perform_unary_ok(Value::calc_neg, Area(Acre)), Some(Area(Acre)));
2476 assert_eq!(perform_unary_ok(Value::calc_neg, Volume(Pint)), Some(Volume(Pint)));
2477 assert_eq!(perform_unary_ok(Value::calc_neg, Speed(Light)), Some(Speed(Light)));
2478 assert_eq!(perform_unary_ok(Value::calc_neg, Mass(Ounce)), Some(Mass(Ounce)));
2479 assert_eq!(perform_unary_ok(Value::calc_neg, Temp(Rankine)), Some(Temp(Rankine)));
2480 assert_eq!(perform_unary_ok(Value::calc_neg, Data(Bit)), Some(Data(Bit)));
2481 }
2482
2483 #[test]
2491 fn test_unit_values_are_inverted_by_meaning() {
2492 assert_eq!(perform_unary_ok(Value::calc_inv, Plain), Some(Plain));
2493 assert_eq!(perform_unary_err(Value::calc_inv, Delta(Hour)), Some(BadCastOp(Delta(Hour), Plain)));
2494 assert_eq!(perform_unary_err(Value::calc_inv, Time), Some(BadCastOp(Time, Plain)));
2495 assert_eq!(perform_unary_err(Value::calc_inv, Length(Mile)), Some(BadCastOp(Length(Mile), Plain)));
2496 assert_eq!(perform_unary_err(Value::calc_inv, Area(Acre)), Some(BadCastOp(Area(Acre), Plain)));
2497 assert_eq!(perform_unary_err(Value::calc_inv, Volume(Pint)), Some(BadCastOp(Volume(Pint), Plain)));
2498 assert_eq!(perform_unary_err(Value::calc_inv, Speed(Light)), Some(BadCastOp(Speed(Light), Plain)));
2499 assert_eq!(perform_unary_err(Value::calc_inv, Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Plain)));
2500 assert_eq!(perform_unary_err(Value::calc_inv, Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Plain)));
2501 assert_eq!(perform_unary_err(Value::calc_inv, Data(Bit)), Some(BadCastOp(Data(Bit), Plain)));
2502 }
2503
2504 #[test]
2513 fn test_unit_values_are_raised_by_meaning() {
2514 assert_eq!(perform_binary_ok(Value::calc_pow, Plain, Plain), Some(Plain));
2515 assert_eq!(perform_binary_err(Value::calc_pow, Plain, Delta(Hour)), Some(BadCastOp(Delta(Hour), Plain)));
2516 assert_eq!(perform_binary_err(Value::calc_pow, Plain, Time), Some(BadCastOp(Time, Plain)));
2517 assert_eq!(perform_binary_err(Value::calc_pow, Plain, Length(Mile)), Some(BadCastOp(Length(Mile), Plain)));
2518 assert_eq!(perform_binary_err(Value::calc_pow, Plain, Area(Acre)), Some(BadCastOp(Area(Acre), Plain)));
2519 assert_eq!(perform_binary_err(Value::calc_pow, Plain, Volume(Pint)), Some(BadCastOp(Volume(Pint), Plain)));
2520 assert_eq!(perform_binary_err(Value::calc_pow, Plain, Speed(Light)), Some(BadCastOp(Speed(Light), Plain)));
2521 assert_eq!(perform_binary_err(Value::calc_pow, Plain, Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Plain)));
2522 assert_eq!(perform_binary_err(Value::calc_pow, Plain, Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Plain)));
2523 assert_eq!(perform_binary_err(Value::calc_pow, Plain, Data(Bit)), Some(BadCastOp(Data(Bit), Plain)));
2524
2525 assert_eq!(perform_binary_err(Value::calc_pow, Delta(Hour), Plain), Some(BadCastOp(Plain, Delta(Hour))));
2526 assert_eq!(perform_binary_err(Value::calc_pow, Delta(Hour), Delta(Hour)), Some(BadCastOp(Delta(Hour), Delta(Hour))));
2527 assert_eq!(perform_binary_err(Value::calc_pow, Delta(Hour), Time), Some(BadCastOp(Time, Delta(Hour))));
2528 assert_eq!(perform_binary_err(Value::calc_pow, Delta(Hour), Length(Mile)), Some(BadCastOp(Length(Mile), Delta(Hour))));
2529 assert_eq!(perform_binary_err(Value::calc_pow, Delta(Hour), Area(Acre)), Some(BadCastOp(Area(Acre), Delta(Hour))));
2530 assert_eq!(perform_binary_err(Value::calc_pow, Delta(Hour), Volume(Pint)), Some(BadCastOp(Volume(Pint), Delta(Hour))));
2531 assert_eq!(perform_binary_err(Value::calc_pow, Delta(Hour), Speed(Light)), Some(BadCastOp(Speed(Light), Delta(Hour))));
2532 assert_eq!(perform_binary_err(Value::calc_pow, Delta(Hour), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Delta(Hour))));
2533 assert_eq!(perform_binary_err(Value::calc_pow, Delta(Hour), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Delta(Hour))));
2534 assert_eq!(perform_binary_err(Value::calc_pow, Delta(Hour), Data(Bit)), Some(BadCastOp(Data(Bit), Delta(Hour))));
2535
2536 assert_eq!(perform_binary_err(Value::calc_pow, Time, Plain), Some(BadCastOp(Plain, Time)));
2537 assert_eq!(perform_binary_err(Value::calc_pow, Time, Delta(Hour)), Some(BadCastOp(Delta(Hour), Time)));
2538 assert_eq!(perform_binary_err(Value::calc_pow, Time, Time), Some(BadCastOp(Time, Time)));
2539 assert_eq!(perform_binary_err(Value::calc_pow, Time, Length(Mile)), Some(BadCastOp(Length(Mile), Time)));
2540 assert_eq!(perform_binary_err(Value::calc_pow, Time, Area(Acre)), Some(BadCastOp(Area(Acre), Time)));
2541 assert_eq!(perform_binary_err(Value::calc_pow, Time, Volume(Pint)), Some(BadCastOp(Volume(Pint), Time)));
2542 assert_eq!(perform_binary_err(Value::calc_pow, Time, Speed(Light)), Some(BadCastOp(Speed(Light), Time)));
2543 assert_eq!(perform_binary_err(Value::calc_pow, Time, Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Time)));
2544 assert_eq!(perform_binary_err(Value::calc_pow, Time, Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Time)));
2545 assert_eq!(perform_binary_err(Value::calc_pow, Time, Data(Bit)), Some(BadCastOp(Data(Bit), Time)));
2546
2547 assert_eq!(perform_binary_err(Value::calc_pow, Length(Mile), Plain), Some(BadCastOp(Plain, Length(Mile))));
2548 assert_eq!(perform_binary_err(Value::calc_pow, Length(Mile), Delta(Hour)), Some(BadCastOp(Delta(Hour), Length(Mile))));
2549 assert_eq!(perform_binary_err(Value::calc_pow, Length(Mile), Time), Some(BadCastOp(Time, Length(Mile))));
2550 assert_eq!(perform_binary_err(Value::calc_pow, Length(Mile), Length(Mile)), Some(BadCastOp(Length(Mile), Length(Mile))));
2551 assert_eq!(perform_binary_err(Value::calc_pow, Length(Mile), Area(Acre)), Some(BadCastOp(Area(Acre), Length(Mile))));
2552 assert_eq!(perform_binary_err(Value::calc_pow, Length(Mile), Volume(Pint)), Some(BadCastOp(Volume(Pint), Length(Mile))));
2553 assert_eq!(perform_binary_err(Value::calc_pow, Length(Mile), Speed(Light)), Some(BadCastOp(Speed(Light), Length(Mile))));
2554 assert_eq!(perform_binary_err(Value::calc_pow, Length(Mile), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Length(Mile))));
2555 assert_eq!(perform_binary_err(Value::calc_pow, Length(Mile), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Length(Mile))));
2556 assert_eq!(perform_binary_err(Value::calc_pow, Length(Mile), Data(Bit)), Some(BadCastOp(Data(Bit), Length(Mile))));
2557
2558 assert_eq!(perform_binary_err(Value::calc_pow, Area(Acre), Plain), Some(BadCastOp(Plain, Area(Acre))));
2559 assert_eq!(perform_binary_err(Value::calc_pow, Area(Acre), Delta(Hour)), Some(BadCastOp(Delta(Hour), Area(Acre))));
2560 assert_eq!(perform_binary_err(Value::calc_pow, Area(Acre), Time), Some(BadCastOp(Time, Area(Acre))));
2561 assert_eq!(perform_binary_err(Value::calc_pow, Area(Acre), Length(Mile)), Some(BadCastOp(Length(Mile), Area(Acre))));
2562 assert_eq!(perform_binary_err(Value::calc_pow, Area(Acre), Area(Acre)), Some(BadCastOp(Area(Acre), Area(Acre))));
2563 assert_eq!(perform_binary_err(Value::calc_pow, Area(Acre), Volume(Pint)), Some(BadCastOp(Volume(Pint), Area(Acre))));
2564 assert_eq!(perform_binary_err(Value::calc_pow, Area(Acre), Speed(Light)), Some(BadCastOp(Speed(Light), Area(Acre))));
2565 assert_eq!(perform_binary_err(Value::calc_pow, Area(Acre), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Area(Acre))));
2566 assert_eq!(perform_binary_err(Value::calc_pow, Area(Acre), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Area(Acre))));
2567 assert_eq!(perform_binary_err(Value::calc_pow, Area(Acre), Data(Bit)), Some(BadCastOp(Data(Bit), Area(Acre))));
2568
2569 assert_eq!(perform_binary_err(Value::calc_pow, Volume(Pint), Plain), Some(BadCastOp(Plain, Volume(Pint))));
2570 assert_eq!(perform_binary_err(Value::calc_pow, Volume(Pint), Delta(Hour)), Some(BadCastOp(Delta(Hour), Volume(Pint))));
2571 assert_eq!(perform_binary_err(Value::calc_pow, Volume(Pint), Time), Some(BadCastOp(Time, Volume(Pint))));
2572 assert_eq!(perform_binary_err(Value::calc_pow, Volume(Pint), Length(Mile)), Some(BadCastOp(Length(Mile), Volume(Pint))));
2573 assert_eq!(perform_binary_err(Value::calc_pow, Volume(Pint), Area(Acre)), Some(BadCastOp(Area(Acre), Volume(Pint))));
2574 assert_eq!(perform_binary_err(Value::calc_pow, Volume(Pint), Volume(Pint)), Some(BadCastOp(Volume(Pint), Volume(Pint))));
2575 assert_eq!(perform_binary_err(Value::calc_pow, Volume(Pint), Speed(Light)), Some(BadCastOp(Speed(Light), Volume(Pint))));
2576 assert_eq!(perform_binary_err(Value::calc_pow, Volume(Pint), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Volume(Pint))));
2577 assert_eq!(perform_binary_err(Value::calc_pow, Volume(Pint), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Volume(Pint))));
2578 assert_eq!(perform_binary_err(Value::calc_pow, Volume(Pint), Data(Bit)), Some(BadCastOp(Data(Bit), Volume(Pint))));
2579
2580 assert_eq!(perform_binary_err(Value::calc_pow, Speed(Light), Plain), Some(BadCastOp(Plain, Speed(Light))));
2581 assert_eq!(perform_binary_err(Value::calc_pow, Speed(Light), Delta(Hour)), Some(BadCastOp(Delta(Hour), Speed(Light))));
2582 assert_eq!(perform_binary_err(Value::calc_pow, Speed(Light), Time), Some(BadCastOp(Time, Speed(Light))));
2583 assert_eq!(perform_binary_err(Value::calc_pow, Speed(Light), Length(Mile)), Some(BadCastOp(Length(Mile), Speed(Light))));
2584 assert_eq!(perform_binary_err(Value::calc_pow, Speed(Light), Area(Acre)), Some(BadCastOp(Area(Acre), Speed(Light))));
2585 assert_eq!(perform_binary_err(Value::calc_pow, Speed(Light), Volume(Pint)), Some(BadCastOp(Volume(Pint), Speed(Light))));
2586 assert_eq!(perform_binary_err(Value::calc_pow, Speed(Light), Speed(Light)), Some(BadCastOp(Speed(Light), Speed(Light))));
2587 assert_eq!(perform_binary_err(Value::calc_pow, Speed(Light), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Speed(Light))));
2588 assert_eq!(perform_binary_err(Value::calc_pow, Speed(Light), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Speed(Light))));
2589 assert_eq!(perform_binary_err(Value::calc_pow, Speed(Light), Data(Bit)), Some(BadCastOp(Data(Bit), Speed(Light))));
2590
2591 assert_eq!(perform_binary_err(Value::calc_pow, Mass(Ounce), Plain), Some(BadCastOp(Plain, Mass(Ounce))));
2592 assert_eq!(perform_binary_err(Value::calc_pow, Mass(Ounce), Delta(Hour)), Some(BadCastOp(Delta(Hour), Mass(Ounce))));
2593 assert_eq!(perform_binary_err(Value::calc_pow, Mass(Ounce), Time), Some(BadCastOp(Time, Mass(Ounce))));
2594 assert_eq!(perform_binary_err(Value::calc_pow, Mass(Ounce), Length(Mile)), Some(BadCastOp(Length(Mile), Mass(Ounce))));
2595 assert_eq!(perform_binary_err(Value::calc_pow, Mass(Ounce), Area(Acre)), Some(BadCastOp(Area(Acre), Mass(Ounce))));
2596 assert_eq!(perform_binary_err(Value::calc_pow, Mass(Ounce), Volume(Pint)), Some(BadCastOp(Volume(Pint), Mass(Ounce))));
2597 assert_eq!(perform_binary_err(Value::calc_pow, Mass(Ounce), Speed(Light)), Some(BadCastOp(Speed(Light), Mass(Ounce))));
2598 assert_eq!(perform_binary_err(Value::calc_pow, Mass(Ounce), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Mass(Ounce))));
2599 assert_eq!(perform_binary_err(Value::calc_pow, Mass(Ounce), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Mass(Ounce))));
2600 assert_eq!(perform_binary_err(Value::calc_pow, Mass(Ounce), Data(Bit)), Some(BadCastOp(Data(Bit), Mass(Ounce))));
2601
2602 assert_eq!(perform_binary_err(Value::calc_pow, Temp(Rankine), Plain), Some(BadCastOp(Plain, Temp(Rankine))));
2603 assert_eq!(perform_binary_err(Value::calc_pow, Temp(Rankine), Delta(Hour)), Some(BadCastOp(Delta(Hour), Temp(Rankine))));
2604 assert_eq!(perform_binary_err(Value::calc_pow, Temp(Rankine), Time), Some(BadCastOp(Time, Temp(Rankine))));
2605 assert_eq!(perform_binary_err(Value::calc_pow, Temp(Rankine), Length(Mile)), Some(BadCastOp(Length(Mile), Temp(Rankine))));
2606 assert_eq!(perform_binary_err(Value::calc_pow, Temp(Rankine), Area(Acre)), Some(BadCastOp(Area(Acre), Temp(Rankine))));
2607 assert_eq!(perform_binary_err(Value::calc_pow, Temp(Rankine), Volume(Pint)), Some(BadCastOp(Volume(Pint), Temp(Rankine))));
2608 assert_eq!(perform_binary_err(Value::calc_pow, Temp(Rankine), Speed(Light)), Some(BadCastOp(Speed(Light), Temp(Rankine))));
2609 assert_eq!(perform_binary_err(Value::calc_pow, Temp(Rankine), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Temp(Rankine))));
2610 assert_eq!(perform_binary_err(Value::calc_pow, Temp(Rankine), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Temp(Rankine))));
2611 assert_eq!(perform_binary_err(Value::calc_pow, Temp(Rankine), Data(Bit)), Some(BadCastOp(Data(Bit), Temp(Rankine))));
2612
2613 assert_eq!(perform_binary_err(Value::calc_pow, Data(Bit), Plain), Some(BadCastOp(Plain, Data(Bit))));
2614 assert_eq!(perform_binary_err(Value::calc_pow, Data(Bit), Delta(Hour)), Some(BadCastOp(Delta(Hour), Data(Bit))));
2615 assert_eq!(perform_binary_err(Value::calc_pow, Data(Bit), Time), Some(BadCastOp(Time, Data(Bit))));
2616 assert_eq!(perform_binary_err(Value::calc_pow, Data(Bit), Length(Mile)), Some(BadCastOp(Length(Mile), Data(Bit))));
2617 assert_eq!(perform_binary_err(Value::calc_pow, Data(Bit), Area(Acre)), Some(BadCastOp(Area(Acre), Data(Bit))));
2618 assert_eq!(perform_binary_err(Value::calc_pow, Data(Bit), Volume(Pint)), Some(BadCastOp(Volume(Pint), Data(Bit))));
2619 assert_eq!(perform_binary_err(Value::calc_pow, Data(Bit), Speed(Light)), Some(BadCastOp(Speed(Light), Data(Bit))));
2620 assert_eq!(perform_binary_err(Value::calc_pow, Data(Bit), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Data(Bit))));
2621 assert_eq!(perform_binary_err(Value::calc_pow, Data(Bit), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Data(Bit))));
2622 assert_eq!(perform_binary_err(Value::calc_pow, Data(Bit), Data(Bit)), Some(BadCastOp(Data(Bit), Data(Bit))));
2623 }
2624
2625 #[test]
2633 fn test_plain_values_have_square_root_by_meaning() {
2634 assert_eq!(perform_unary_ok(Value::calc_sqrt, Plain), Some(Plain));
2635 assert_eq!(perform_unary_err(Value::calc_sqrt, Delta(Hour)), Some(BadCastOp(Delta(Hour), Plain)));
2636 assert_eq!(perform_unary_err(Value::calc_sqrt, Time), Some(BadCastOp(Time, Plain)));
2637 assert_eq!(perform_unary_err(Value::calc_sqrt, Length(Mile)), Some(BadCastOp(Length(Mile), Plain)));
2638 assert_eq!(perform_unary_err(Value::calc_sqrt, Area(Acre)), Some(BadCastOp(Area(Acre), Plain)));
2639 assert_eq!(perform_unary_err(Value::calc_sqrt, Volume(Pint)), Some(BadCastOp(Volume(Pint), Plain)));
2640 assert_eq!(perform_unary_err(Value::calc_sqrt, Speed(Light)), Some(BadCastOp(Speed(Light), Plain)));
2641 assert_eq!(perform_unary_err(Value::calc_sqrt, Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Plain)));
2642 assert_eq!(perform_unary_err(Value::calc_sqrt, Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Plain)));
2643 assert_eq!(perform_unary_err(Value::calc_sqrt, Data(Bit)), Some(BadCastOp(Data(Bit), Plain)));
2644 }
2645
2646 #[test]
2655 fn test_plain_values_have_bitwise_and_by_meaning() {
2656 assert_eq!(perform_binary_ok(Value::calc_and, Plain, Plain), Some(Plain));
2657 assert_eq!(perform_binary_err(Value::calc_and, Plain, Delta(Hour)), Some(BadCastOp(Delta(Hour), Plain)));
2658 assert_eq!(perform_binary_err(Value::calc_and, Plain, Time), Some(BadCastOp(Time, Plain)));
2659 assert_eq!(perform_binary_err(Value::calc_and, Delta(Hour), Plain), Some(BadCastOp(Plain, Delta(Hour))));
2660 assert_eq!(perform_binary_err(Value::calc_and, Delta(Hour), Delta(Hour)), Some(BadCastOp(Delta(Hour), Delta(Hour))));
2661 assert_eq!(perform_binary_err(Value::calc_and, Delta(Hour), Time), Some(BadCastOp(Time, Delta(Hour))));
2662 assert_eq!(perform_binary_err(Value::calc_and, Time, Plain), Some(BadCastOp(Plain, Time)));
2663 assert_eq!(perform_binary_err(Value::calc_and, Time, Delta(Hour)), Some(BadCastOp(Delta(Hour), Time)));
2664 assert_eq!(perform_binary_err(Value::calc_and, Time, Time), Some(BadCastOp(Time, Time)));
2665 }
2666
2667 #[test]
2668 fn test_plain_values_have_bitwise_or_by_meaning() {
2669 assert_eq!(perform_binary_ok(Value::calc_or, Plain, Plain), Some(Plain));
2670 assert_eq!(perform_binary_err(Value::calc_or, Plain, Delta(Hour)), Some(BadCastOp(Delta(Hour), Plain)));
2671 assert_eq!(perform_binary_err(Value::calc_or, Plain, Time), Some(BadCastOp(Time, Plain)));
2672 assert_eq!(perform_binary_err(Value::calc_or, Delta(Hour), Plain), Some(BadCastOp(Plain, Delta(Hour))));
2673 assert_eq!(perform_binary_err(Value::calc_or, Delta(Hour), Delta(Hour)), Some(BadCastOp(Delta(Hour), Delta(Hour))));
2674 assert_eq!(perform_binary_err(Value::calc_or, Delta(Hour), Time), Some(BadCastOp(Time, Delta(Hour))));
2675 assert_eq!(perform_binary_err(Value::calc_or, Time, Plain), Some(BadCastOp(Plain, Time)));
2676 assert_eq!(perform_binary_err(Value::calc_or, Time, Delta(Hour)), Some(BadCastOp(Delta(Hour), Time)));
2677 assert_eq!(perform_binary_err(Value::calc_or, Time, Time), Some(BadCastOp(Time, Time)));
2678 }
2679
2680 #[test]
2681 fn test_plain_values_have_bitwise_xor_by_meaning() {
2682 assert_eq!(perform_binary_ok(Value::calc_xor, Plain, Plain), Some(Plain));
2683 assert_eq!(perform_binary_err(Value::calc_xor, Plain, Delta(Hour)), Some(BadCastOp(Delta(Hour), Plain)));
2684 assert_eq!(perform_binary_err(Value::calc_xor, Plain, Time), Some(BadCastOp(Time, Plain)));
2685 assert_eq!(perform_binary_err(Value::calc_xor, Delta(Hour), Plain), Some(BadCastOp(Plain, Delta(Hour))));
2686 assert_eq!(perform_binary_err(Value::calc_xor, Delta(Hour), Delta(Hour)), Some(BadCastOp(Delta(Hour), Delta(Hour))));
2687 assert_eq!(perform_binary_err(Value::calc_xor, Delta(Hour), Time), Some(BadCastOp(Time, Delta(Hour))));
2688 assert_eq!(perform_binary_err(Value::calc_xor, Time, Plain), Some(BadCastOp(Plain, Time)));
2689 assert_eq!(perform_binary_err(Value::calc_xor, Time, Delta(Hour)), Some(BadCastOp(Delta(Hour), Time)));
2690 assert_eq!(perform_binary_err(Value::calc_xor, Time, Time), Some(BadCastOp(Time, Time)));
2691 }
2692
2693 #[test]
2694 fn test_unit_values_are_shifted_left_by_meaning() {
2695 assert_eq!(perform_binary_ok(Value::calc_shl, Plain, Plain), Some(Plain));
2696 assert_eq!(perform_binary_err(Value::calc_shl, Plain, Delta(Hour)), Some(BadCastOp(Delta(Hour), Plain)));
2697 assert_eq!(perform_binary_err(Value::calc_shl, Plain, Time), Some(BadCastOp(Time, Plain)));
2698 assert_eq!(perform_binary_err(Value::calc_shl, Plain, Length(Mile)), Some(BadCastOp(Length(Mile), Plain)));
2699 assert_eq!(perform_binary_err(Value::calc_shl, Plain, Area(Acre)), Some(BadCastOp(Area(Acre), Plain)));
2700 assert_eq!(perform_binary_err(Value::calc_shl, Plain, Volume(Pint)), Some(BadCastOp(Volume(Pint), Plain)));
2701 assert_eq!(perform_binary_err(Value::calc_shl, Plain, Speed(Light)), Some(BadCastOp(Speed(Light), Plain)));
2702 assert_eq!(perform_binary_err(Value::calc_shl, Plain, Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Plain)));
2703 assert_eq!(perform_binary_err(Value::calc_shl, Plain, Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Plain)));
2704 assert_eq!(perform_binary_err(Value::calc_shl, Plain, Data(Bit)), Some(BadCastOp(Data(Bit), Plain)));
2705
2706 assert_eq!(perform_binary_err(Value::calc_shl, Delta(Hour), Plain), Some(BadCastOp(Plain, Delta(Hour))));
2707 assert_eq!(perform_binary_err(Value::calc_shl, Delta(Hour), Delta(Hour)), Some(BadCastOp(Delta(Hour), Delta(Hour))));
2708 assert_eq!(perform_binary_err(Value::calc_shl, Delta(Hour), Time), Some(BadCastOp(Time, Delta(Hour))));
2709 assert_eq!(perform_binary_err(Value::calc_shl, Delta(Hour), Length(Mile)), Some(BadCastOp(Length(Mile), Delta(Hour))));
2710 assert_eq!(perform_binary_err(Value::calc_shl, Delta(Hour), Area(Acre)), Some(BadCastOp(Area(Acre), Delta(Hour))));
2711 assert_eq!(perform_binary_err(Value::calc_shl, Delta(Hour), Volume(Pint)), Some(BadCastOp(Volume(Pint), Delta(Hour))));
2712 assert_eq!(perform_binary_err(Value::calc_shl, Delta(Hour), Speed(Light)), Some(BadCastOp(Speed(Light), Delta(Hour))));
2713 assert_eq!(perform_binary_err(Value::calc_shl, Delta(Hour), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Delta(Hour))));
2714 assert_eq!(perform_binary_err(Value::calc_shl, Delta(Hour), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Delta(Hour))));
2715 assert_eq!(perform_binary_err(Value::calc_shl, Delta(Hour), Data(Bit)), Some(BadCastOp(Data(Bit), Delta(Hour))));
2716
2717 assert_eq!(perform_binary_err(Value::calc_shl, Time, Plain), Some(BadCastOp(Plain, Time)));
2718 assert_eq!(perform_binary_err(Value::calc_shl, Time, Delta(Hour)), Some(BadCastOp(Delta(Hour), Time)));
2719 assert_eq!(perform_binary_err(Value::calc_shl, Time, Time), Some(BadCastOp(Time, Time)));
2720 assert_eq!(perform_binary_err(Value::calc_shl, Time, Length(Mile)), Some(BadCastOp(Length(Mile), Time)));
2721 assert_eq!(perform_binary_err(Value::calc_shl, Time, Area(Acre)), Some(BadCastOp(Area(Acre), Time)));
2722 assert_eq!(perform_binary_err(Value::calc_shl, Time, Volume(Pint)), Some(BadCastOp(Volume(Pint), Time)));
2723 assert_eq!(perform_binary_err(Value::calc_shl, Time, Speed(Light)), Some(BadCastOp(Speed(Light), Time)));
2724 assert_eq!(perform_binary_err(Value::calc_shl, Time, Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Time)));
2725 assert_eq!(perform_binary_err(Value::calc_shl, Time, Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Time)));
2726 assert_eq!(perform_binary_err(Value::calc_shl, Time, Data(Bit)), Some(BadCastOp(Data(Bit), Time)));
2727
2728 assert_eq!(perform_binary_err(Value::calc_shl, Length(Mile), Plain), Some(BadCastOp(Plain, Length(Mile))));
2729 assert_eq!(perform_binary_err(Value::calc_shl, Length(Mile), Delta(Hour)), Some(BadCastOp(Delta(Hour), Length(Mile))));
2730 assert_eq!(perform_binary_err(Value::calc_shl, Length(Mile), Time), Some(BadCastOp(Time, Length(Mile))));
2731 assert_eq!(perform_binary_err(Value::calc_shl, Length(Mile), Length(Mile)), Some(BadCastOp(Length(Mile), Length(Mile))));
2732 assert_eq!(perform_binary_err(Value::calc_shl, Length(Mile), Area(Acre)), Some(BadCastOp(Area(Acre), Length(Mile))));
2733 assert_eq!(perform_binary_err(Value::calc_shl, Length(Mile), Volume(Pint)), Some(BadCastOp(Volume(Pint), Length(Mile))));
2734 assert_eq!(perform_binary_err(Value::calc_shl, Length(Mile), Speed(Light)), Some(BadCastOp(Speed(Light), Length(Mile))));
2735 assert_eq!(perform_binary_err(Value::calc_shl, Length(Mile), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Length(Mile))));
2736 assert_eq!(perform_binary_err(Value::calc_shl, Length(Mile), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Length(Mile))));
2737 assert_eq!(perform_binary_err(Value::calc_shl, Length(Mile), Data(Bit)), Some(BadCastOp(Data(Bit), Length(Mile))));
2738
2739 assert_eq!(perform_binary_err(Value::calc_shl, Area(Acre), Plain), Some(BadCastOp(Plain, Area(Acre))));
2740 assert_eq!(perform_binary_err(Value::calc_shl, Area(Acre), Delta(Hour)), Some(BadCastOp(Delta(Hour), Area(Acre))));
2741 assert_eq!(perform_binary_err(Value::calc_shl, Area(Acre), Time), Some(BadCastOp(Time, Area(Acre))));
2742 assert_eq!(perform_binary_err(Value::calc_shl, Area(Acre), Length(Mile)), Some(BadCastOp(Length(Mile), Area(Acre))));
2743 assert_eq!(perform_binary_err(Value::calc_shl, Area(Acre), Area(Acre)), Some(BadCastOp(Area(Acre), Area(Acre))));
2744 assert_eq!(perform_binary_err(Value::calc_shl, Area(Acre), Volume(Pint)), Some(BadCastOp(Volume(Pint), Area(Acre))));
2745 assert_eq!(perform_binary_err(Value::calc_shl, Area(Acre), Speed(Light)), Some(BadCastOp(Speed(Light), Area(Acre))));
2746 assert_eq!(perform_binary_err(Value::calc_shl, Area(Acre), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Area(Acre))));
2747 assert_eq!(perform_binary_err(Value::calc_shl, Area(Acre), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Area(Acre))));
2748 assert_eq!(perform_binary_err(Value::calc_shl, Area(Acre), Data(Bit)), Some(BadCastOp(Data(Bit), Area(Acre))));
2749
2750 assert_eq!(perform_binary_err(Value::calc_shl, Volume(Pint), Plain), Some(BadCastOp(Plain, Volume(Pint))));
2751 assert_eq!(perform_binary_err(Value::calc_shl, Volume(Pint), Delta(Hour)), Some(BadCastOp(Delta(Hour), Volume(Pint))));
2752 assert_eq!(perform_binary_err(Value::calc_shl, Volume(Pint), Time), Some(BadCastOp(Time, Volume(Pint))));
2753 assert_eq!(perform_binary_err(Value::calc_shl, Volume(Pint), Length(Mile)), Some(BadCastOp(Length(Mile), Volume(Pint))));
2754 assert_eq!(perform_binary_err(Value::calc_shl, Volume(Pint), Area(Acre)), Some(BadCastOp(Area(Acre), Volume(Pint))));
2755 assert_eq!(perform_binary_err(Value::calc_shl, Volume(Pint), Volume(Pint)), Some(BadCastOp(Volume(Pint), Volume(Pint))));
2756 assert_eq!(perform_binary_err(Value::calc_shl, Volume(Pint), Speed(Light)), Some(BadCastOp(Speed(Light), Volume(Pint))));
2757 assert_eq!(perform_binary_err(Value::calc_shl, Volume(Pint), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Volume(Pint))));
2758 assert_eq!(perform_binary_err(Value::calc_shl, Volume(Pint), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Volume(Pint))));
2759 assert_eq!(perform_binary_err(Value::calc_shl, Volume(Pint), Data(Bit)), Some(BadCastOp(Data(Bit), Volume(Pint))));
2760
2761 assert_eq!(perform_binary_err(Value::calc_shl, Speed(Light), Plain), Some(BadCastOp(Plain, Speed(Light))));
2762 assert_eq!(perform_binary_err(Value::calc_shl, Speed(Light), Delta(Hour)), Some(BadCastOp(Delta(Hour), Speed(Light))));
2763 assert_eq!(perform_binary_err(Value::calc_shl, Speed(Light), Time), Some(BadCastOp(Time, Speed(Light))));
2764 assert_eq!(perform_binary_err(Value::calc_shl, Speed(Light), Length(Mile)), Some(BadCastOp(Length(Mile), Speed(Light))));
2765 assert_eq!(perform_binary_err(Value::calc_shl, Speed(Light), Area(Acre)), Some(BadCastOp(Area(Acre), Speed(Light))));
2766 assert_eq!(perform_binary_err(Value::calc_shl, Speed(Light), Volume(Pint)), Some(BadCastOp(Volume(Pint), Speed(Light))));
2767 assert_eq!(perform_binary_err(Value::calc_shl, Speed(Light), Speed(Light)), Some(BadCastOp(Speed(Light), Speed(Light))));
2768 assert_eq!(perform_binary_err(Value::calc_shl, Speed(Light), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Speed(Light))));
2769 assert_eq!(perform_binary_err(Value::calc_shl, Speed(Light), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Speed(Light))));
2770 assert_eq!(perform_binary_err(Value::calc_shl, Speed(Light), Data(Bit)), Some(BadCastOp(Data(Bit), Speed(Light))));
2771
2772 assert_eq!(perform_binary_err(Value::calc_shl, Mass(Ounce), Plain), Some(BadCastOp(Plain, Mass(Ounce))));
2773 assert_eq!(perform_binary_err(Value::calc_shl, Mass(Ounce), Delta(Hour)), Some(BadCastOp(Delta(Hour), Mass(Ounce))));
2774 assert_eq!(perform_binary_err(Value::calc_shl, Mass(Ounce), Time), Some(BadCastOp(Time, Mass(Ounce))));
2775 assert_eq!(perform_binary_err(Value::calc_shl, Mass(Ounce), Length(Mile)), Some(BadCastOp(Length(Mile), Mass(Ounce))));
2776 assert_eq!(perform_binary_err(Value::calc_shl, Mass(Ounce), Area(Acre)), Some(BadCastOp(Area(Acre), Mass(Ounce))));
2777 assert_eq!(perform_binary_err(Value::calc_shl, Mass(Ounce), Volume(Pint)), Some(BadCastOp(Volume(Pint), Mass(Ounce))));
2778 assert_eq!(perform_binary_err(Value::calc_shl, Mass(Ounce), Speed(Light)), Some(BadCastOp(Speed(Light), Mass(Ounce))));
2779 assert_eq!(perform_binary_err(Value::calc_shl, Mass(Ounce), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Mass(Ounce))));
2780 assert_eq!(perform_binary_err(Value::calc_shl, Mass(Ounce), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Mass(Ounce))));
2781 assert_eq!(perform_binary_err(Value::calc_shl, Mass(Ounce), Data(Bit)), Some(BadCastOp(Data(Bit), Mass(Ounce))));
2782
2783 assert_eq!(perform_binary_err(Value::calc_shl, Temp(Rankine), Plain), Some(BadCastOp(Plain, Temp(Rankine))));
2784 assert_eq!(perform_binary_err(Value::calc_shl, Temp(Rankine), Delta(Hour)), Some(BadCastOp(Delta(Hour), Temp(Rankine))));
2785 assert_eq!(perform_binary_err(Value::calc_shl, Temp(Rankine), Time), Some(BadCastOp(Time, Temp(Rankine))));
2786 assert_eq!(perform_binary_err(Value::calc_shl, Temp(Rankine), Length(Mile)), Some(BadCastOp(Length(Mile), Temp(Rankine))));
2787 assert_eq!(perform_binary_err(Value::calc_shl, Temp(Rankine), Area(Acre)), Some(BadCastOp(Area(Acre), Temp(Rankine))));
2788 assert_eq!(perform_binary_err(Value::calc_shl, Temp(Rankine), Volume(Pint)), Some(BadCastOp(Volume(Pint), Temp(Rankine))));
2789 assert_eq!(perform_binary_err(Value::calc_shl, Temp(Rankine), Speed(Light)), Some(BadCastOp(Speed(Light), Temp(Rankine))));
2790 assert_eq!(perform_binary_err(Value::calc_shl, Temp(Rankine), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Temp(Rankine))));
2791 assert_eq!(perform_binary_err(Value::calc_shl, Temp(Rankine), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Temp(Rankine))));
2792 assert_eq!(perform_binary_err(Value::calc_shl, Temp(Rankine), Data(Bit)), Some(BadCastOp(Data(Bit), Temp(Rankine))));
2793
2794 assert_eq!(perform_binary_err(Value::calc_shl, Data(Bit), Plain), Some(BadCastOp(Plain, Data(Bit))));
2795 assert_eq!(perform_binary_err(Value::calc_shl, Data(Bit), Delta(Hour)), Some(BadCastOp(Delta(Hour), Data(Bit))));
2796 assert_eq!(perform_binary_err(Value::calc_shl, Data(Bit), Time), Some(BadCastOp(Time, Data(Bit))));
2797 assert_eq!(perform_binary_err(Value::calc_shl, Data(Bit), Length(Mile)), Some(BadCastOp(Length(Mile), Data(Bit))));
2798 assert_eq!(perform_binary_err(Value::calc_shl, Data(Bit), Area(Acre)), Some(BadCastOp(Area(Acre), Data(Bit))));
2799 assert_eq!(perform_binary_err(Value::calc_shl, Data(Bit), Volume(Pint)), Some(BadCastOp(Volume(Pint), Data(Bit))));
2800 assert_eq!(perform_binary_err(Value::calc_shl, Data(Bit), Speed(Light)), Some(BadCastOp(Speed(Light), Data(Bit))));
2801 assert_eq!(perform_binary_err(Value::calc_shl, Data(Bit), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Data(Bit))));
2802 assert_eq!(perform_binary_err(Value::calc_shl, Data(Bit), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Data(Bit))));
2803 assert_eq!(perform_binary_err(Value::calc_shl, Data(Bit), Data(Bit)), Some(BadCastOp(Data(Bit), Data(Bit))));
2804 }
2805
2806 #[test]
2807 fn test_unit_values_are_shifted_right_by_meaning() {
2808 assert_eq!(perform_binary_ok(Value::calc_shr, Plain, Plain), Some(Plain));
2809 assert_eq!(perform_binary_err(Value::calc_shr, Plain, Delta(Hour)), Some(BadCastOp(Delta(Hour), Plain)));
2810 assert_eq!(perform_binary_err(Value::calc_shr, Plain, Time), Some(BadCastOp(Time, Plain)));
2811 assert_eq!(perform_binary_err(Value::calc_shr, Plain, Length(Mile)), Some(BadCastOp(Length(Mile), Plain)));
2812 assert_eq!(perform_binary_err(Value::calc_shr, Plain, Area(Acre)), Some(BadCastOp(Area(Acre), Plain)));
2813 assert_eq!(perform_binary_err(Value::calc_shr, Plain, Volume(Pint)), Some(BadCastOp(Volume(Pint), Plain)));
2814 assert_eq!(perform_binary_err(Value::calc_shr, Plain, Speed(Light)), Some(BadCastOp(Speed(Light), Plain)));
2815 assert_eq!(perform_binary_err(Value::calc_shr, Plain, Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Plain)));
2816 assert_eq!(perform_binary_err(Value::calc_shr, Plain, Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Plain)));
2817 assert_eq!(perform_binary_err(Value::calc_shr, Plain, Data(Bit)), Some(BadCastOp(Data(Bit), Plain)));
2818
2819 assert_eq!(perform_binary_err(Value::calc_shr, Delta(Hour), Plain), Some(BadCastOp(Plain, Delta(Hour))));
2820 assert_eq!(perform_binary_err(Value::calc_shr, Delta(Hour), Delta(Hour)), Some(BadCastOp(Delta(Hour), Delta(Hour))));
2821 assert_eq!(perform_binary_err(Value::calc_shr, Delta(Hour), Time), Some(BadCastOp(Time, Delta(Hour))));
2822 assert_eq!(perform_binary_err(Value::calc_shr, Delta(Hour), Length(Mile)), Some(BadCastOp(Length(Mile), Delta(Hour))));
2823 assert_eq!(perform_binary_err(Value::calc_shr, Delta(Hour), Area(Acre)), Some(BadCastOp(Area(Acre), Delta(Hour))));
2824 assert_eq!(perform_binary_err(Value::calc_shr, Delta(Hour), Volume(Pint)), Some(BadCastOp(Volume(Pint), Delta(Hour))));
2825 assert_eq!(perform_binary_err(Value::calc_shr, Delta(Hour), Speed(Light)), Some(BadCastOp(Speed(Light), Delta(Hour))));
2826 assert_eq!(perform_binary_err(Value::calc_shr, Delta(Hour), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Delta(Hour))));
2827 assert_eq!(perform_binary_err(Value::calc_shr, Delta(Hour), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Delta(Hour))));
2828 assert_eq!(perform_binary_err(Value::calc_shr, Delta(Hour), Data(Bit)), Some(BadCastOp(Data(Bit), Delta(Hour))));
2829
2830 assert_eq!(perform_binary_err(Value::calc_shr, Time, Plain), Some(BadCastOp(Plain, Time)));
2831 assert_eq!(perform_binary_err(Value::calc_shr, Time, Delta(Hour)), Some(BadCastOp(Delta(Hour), Time)));
2832 assert_eq!(perform_binary_err(Value::calc_shr, Time, Time), Some(BadCastOp(Time, Time)));
2833 assert_eq!(perform_binary_err(Value::calc_shr, Time, Length(Mile)), Some(BadCastOp(Length(Mile), Time)));
2834 assert_eq!(perform_binary_err(Value::calc_shr, Time, Area(Acre)), Some(BadCastOp(Area(Acre), Time)));
2835 assert_eq!(perform_binary_err(Value::calc_shr, Time, Volume(Pint)), Some(BadCastOp(Volume(Pint), Time)));
2836 assert_eq!(perform_binary_err(Value::calc_shr, Time, Speed(Light)), Some(BadCastOp(Speed(Light), Time)));
2837 assert_eq!(perform_binary_err(Value::calc_shr, Time, Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Time)));
2838 assert_eq!(perform_binary_err(Value::calc_shr, Time, Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Time)));
2839 assert_eq!(perform_binary_err(Value::calc_shr, Time, Data(Bit)), Some(BadCastOp(Data(Bit), Time)));
2840
2841 assert_eq!(perform_binary_err(Value::calc_shr, Length(Mile), Plain), Some(BadCastOp(Plain, Length(Mile))));
2842 assert_eq!(perform_binary_err(Value::calc_shr, Length(Mile), Delta(Hour)), Some(BadCastOp(Delta(Hour), Length(Mile))));
2843 assert_eq!(perform_binary_err(Value::calc_shr, Length(Mile), Time), Some(BadCastOp(Time, Length(Mile))));
2844 assert_eq!(perform_binary_err(Value::calc_shr, Length(Mile), Length(Mile)), Some(BadCastOp(Length(Mile), Length(Mile))));
2845 assert_eq!(perform_binary_err(Value::calc_shr, Length(Mile), Area(Acre)), Some(BadCastOp(Area(Acre), Length(Mile))));
2846 assert_eq!(perform_binary_err(Value::calc_shr, Length(Mile), Volume(Pint)), Some(BadCastOp(Volume(Pint), Length(Mile))));
2847 assert_eq!(perform_binary_err(Value::calc_shr, Length(Mile), Speed(Light)), Some(BadCastOp(Speed(Light), Length(Mile))));
2848 assert_eq!(perform_binary_err(Value::calc_shr, Length(Mile), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Length(Mile))));
2849 assert_eq!(perform_binary_err(Value::calc_shr, Length(Mile), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Length(Mile))));
2850 assert_eq!(perform_binary_err(Value::calc_shr, Length(Mile), Data(Bit)), Some(BadCastOp(Data(Bit), Length(Mile))));
2851
2852 assert_eq!(perform_binary_err(Value::calc_shr, Area(Acre), Plain), Some(BadCastOp(Plain, Area(Acre))));
2853 assert_eq!(perform_binary_err(Value::calc_shr, Area(Acre), Delta(Hour)), Some(BadCastOp(Delta(Hour), Area(Acre))));
2854 assert_eq!(perform_binary_err(Value::calc_shr, Area(Acre), Time), Some(BadCastOp(Time, Area(Acre))));
2855 assert_eq!(perform_binary_err(Value::calc_shr, Area(Acre), Length(Mile)), Some(BadCastOp(Length(Mile), Area(Acre))));
2856 assert_eq!(perform_binary_err(Value::calc_shr, Area(Acre), Area(Acre)), Some(BadCastOp(Area(Acre), Area(Acre))));
2857 assert_eq!(perform_binary_err(Value::calc_shr, Area(Acre), Volume(Pint)), Some(BadCastOp(Volume(Pint), Area(Acre))));
2858 assert_eq!(perform_binary_err(Value::calc_shr, Area(Acre), Speed(Light)), Some(BadCastOp(Speed(Light), Area(Acre))));
2859 assert_eq!(perform_binary_err(Value::calc_shr, Area(Acre), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Area(Acre))));
2860 assert_eq!(perform_binary_err(Value::calc_shr, Area(Acre), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Area(Acre))));
2861 assert_eq!(perform_binary_err(Value::calc_shr, Area(Acre), Data(Bit)), Some(BadCastOp(Data(Bit), Area(Acre))));
2862
2863 assert_eq!(perform_binary_err(Value::calc_shr, Volume(Pint), Plain), Some(BadCastOp(Plain, Volume(Pint))));
2864 assert_eq!(perform_binary_err(Value::calc_shr, Volume(Pint), Delta(Hour)), Some(BadCastOp(Delta(Hour), Volume(Pint))));
2865 assert_eq!(perform_binary_err(Value::calc_shr, Volume(Pint), Time), Some(BadCastOp(Time, Volume(Pint))));
2866 assert_eq!(perform_binary_err(Value::calc_shr, Volume(Pint), Length(Mile)), Some(BadCastOp(Length(Mile), Volume(Pint))));
2867 assert_eq!(perform_binary_err(Value::calc_shr, Volume(Pint), Area(Acre)), Some(BadCastOp(Area(Acre), Volume(Pint))));
2868 assert_eq!(perform_binary_err(Value::calc_shr, Volume(Pint), Volume(Pint)), Some(BadCastOp(Volume(Pint), Volume(Pint))));
2869 assert_eq!(perform_binary_err(Value::calc_shr, Volume(Pint), Speed(Light)), Some(BadCastOp(Speed(Light), Volume(Pint))));
2870 assert_eq!(perform_binary_err(Value::calc_shr, Volume(Pint), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Volume(Pint))));
2871 assert_eq!(perform_binary_err(Value::calc_shr, Volume(Pint), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Volume(Pint))));
2872 assert_eq!(perform_binary_err(Value::calc_shr, Volume(Pint), Data(Bit)), Some(BadCastOp(Data(Bit), Volume(Pint))));
2873
2874 assert_eq!(perform_binary_err(Value::calc_shr, Speed(Light), Plain), Some(BadCastOp(Plain, Speed(Light))));
2875 assert_eq!(perform_binary_err(Value::calc_shr, Speed(Light), Delta(Hour)), Some(BadCastOp(Delta(Hour), Speed(Light))));
2876 assert_eq!(perform_binary_err(Value::calc_shr, Speed(Light), Time), Some(BadCastOp(Time, Speed(Light))));
2877 assert_eq!(perform_binary_err(Value::calc_shr, Speed(Light), Length(Mile)), Some(BadCastOp(Length(Mile), Speed(Light))));
2878 assert_eq!(perform_binary_err(Value::calc_shr, Speed(Light), Area(Acre)), Some(BadCastOp(Area(Acre), Speed(Light))));
2879 assert_eq!(perform_binary_err(Value::calc_shr, Speed(Light), Volume(Pint)), Some(BadCastOp(Volume(Pint), Speed(Light))));
2880 assert_eq!(perform_binary_err(Value::calc_shr, Speed(Light), Speed(Light)), Some(BadCastOp(Speed(Light), Speed(Light))));
2881 assert_eq!(perform_binary_err(Value::calc_shr, Speed(Light), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Speed(Light))));
2882 assert_eq!(perform_binary_err(Value::calc_shr, Speed(Light), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Speed(Light))));
2883 assert_eq!(perform_binary_err(Value::calc_shr, Speed(Light), Data(Bit)), Some(BadCastOp(Data(Bit), Speed(Light))));
2884
2885 assert_eq!(perform_binary_err(Value::calc_shr, Mass(Ounce), Plain), Some(BadCastOp(Plain, Mass(Ounce))));
2886 assert_eq!(perform_binary_err(Value::calc_shr, Mass(Ounce), Delta(Hour)), Some(BadCastOp(Delta(Hour), Mass(Ounce))));
2887 assert_eq!(perform_binary_err(Value::calc_shr, Mass(Ounce), Time), Some(BadCastOp(Time, Mass(Ounce))));
2888 assert_eq!(perform_binary_err(Value::calc_shr, Mass(Ounce), Length(Mile)), Some(BadCastOp(Length(Mile), Mass(Ounce))));
2889 assert_eq!(perform_binary_err(Value::calc_shr, Mass(Ounce), Area(Acre)), Some(BadCastOp(Area(Acre), Mass(Ounce))));
2890 assert_eq!(perform_binary_err(Value::calc_shr, Mass(Ounce), Volume(Pint)), Some(BadCastOp(Volume(Pint), Mass(Ounce))));
2891 assert_eq!(perform_binary_err(Value::calc_shr, Mass(Ounce), Speed(Light)), Some(BadCastOp(Speed(Light), Mass(Ounce))));
2892 assert_eq!(perform_binary_err(Value::calc_shr, Mass(Ounce), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Mass(Ounce))));
2893 assert_eq!(perform_binary_err(Value::calc_shr, Mass(Ounce), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Mass(Ounce))));
2894 assert_eq!(perform_binary_err(Value::calc_shr, Mass(Ounce), Data(Bit)), Some(BadCastOp(Data(Bit), Mass(Ounce))));
2895
2896 assert_eq!(perform_binary_err(Value::calc_shr, Temp(Rankine), Plain), Some(BadCastOp(Plain, Temp(Rankine))));
2897 assert_eq!(perform_binary_err(Value::calc_shr, Temp(Rankine), Delta(Hour)), Some(BadCastOp(Delta(Hour), Temp(Rankine))));
2898 assert_eq!(perform_binary_err(Value::calc_shr, Temp(Rankine), Time), Some(BadCastOp(Time, Temp(Rankine))));
2899 assert_eq!(perform_binary_err(Value::calc_shr, Temp(Rankine), Length(Mile)), Some(BadCastOp(Length(Mile), Temp(Rankine))));
2900 assert_eq!(perform_binary_err(Value::calc_shr, Temp(Rankine), Area(Acre)), Some(BadCastOp(Area(Acre), Temp(Rankine))));
2901 assert_eq!(perform_binary_err(Value::calc_shr, Temp(Rankine), Volume(Pint)), Some(BadCastOp(Volume(Pint), Temp(Rankine))));
2902 assert_eq!(perform_binary_err(Value::calc_shr, Temp(Rankine), Speed(Light)), Some(BadCastOp(Speed(Light), Temp(Rankine))));
2903 assert_eq!(perform_binary_err(Value::calc_shr, Temp(Rankine), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Temp(Rankine))));
2904 assert_eq!(perform_binary_err(Value::calc_shr, Temp(Rankine), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Temp(Rankine))));
2905 assert_eq!(perform_binary_err(Value::calc_shr, Temp(Rankine), Data(Bit)), Some(BadCastOp(Data(Bit), Temp(Rankine))));
2906
2907 assert_eq!(perform_binary_err(Value::calc_shr, Data(Bit), Plain), Some(BadCastOp(Plain, Data(Bit))));
2908 assert_eq!(perform_binary_err(Value::calc_shr, Data(Bit), Delta(Hour)), Some(BadCastOp(Delta(Hour), Data(Bit))));
2909 assert_eq!(perform_binary_err(Value::calc_shr, Data(Bit), Time), Some(BadCastOp(Time, Data(Bit))));
2910 assert_eq!(perform_binary_err(Value::calc_shr, Data(Bit), Length(Mile)), Some(BadCastOp(Length(Mile), Data(Bit))));
2911 assert_eq!(perform_binary_err(Value::calc_shr, Data(Bit), Area(Acre)), Some(BadCastOp(Area(Acre), Data(Bit))));
2912 assert_eq!(perform_binary_err(Value::calc_shr, Data(Bit), Volume(Pint)), Some(BadCastOp(Volume(Pint), Data(Bit))));
2913 assert_eq!(perform_binary_err(Value::calc_shr, Data(Bit), Speed(Light)), Some(BadCastOp(Speed(Light), Data(Bit))));
2914 assert_eq!(perform_binary_err(Value::calc_shr, Data(Bit), Mass(Ounce)), Some(BadCastOp(Mass(Ounce), Data(Bit))));
2915 assert_eq!(perform_binary_err(Value::calc_shr, Data(Bit), Temp(Rankine)), Some(BadCastOp(Temp(Rankine), Data(Bit))));
2916 assert_eq!(perform_binary_err(Value::calc_shr, Data(Bit), Data(Bit)), Some(BadCastOp(Data(Bit), Data(Bit))));
2917 }
2918
2919 fn perform_cast_ok(
2920 lhs: Meaning,
2921 rhs: Meaning,
2922 ) -> Option<Meaning> {
2923 let value = create_value(1, 1).with_meaning(lhs);
2924 let result = value.apply_meaning(rhs);
2925 result.ok().map(get_meaning_only)
2926 }
2927
2928 fn perform_cast_value(
2929 lhs: Meaning,
2930 rhs: Meaning,
2931 ) -> Option<(Meaning, String)> {
2932 let value = create_value(1, 1).with_meaning(lhs);
2933 let result = value.apply_meaning(rhs);
2934 result.ok().map(get_meaning_value)
2935 }
2936
2937 fn perform_cast_temp(
2938 lhs: Meaning,
2939 rhs: Meaning,
2940 number: &str,
2941 ) -> Option<(Meaning, String)> {
2942 let value = Value::from_string(number).unwrap().with_meaning(lhs);
2943 let result = value.apply_meaning(rhs);
2944 result.ok().map(get_meaning_value)
2945 }
2946
2947 fn perform_cast_err(
2948 lhs: Meaning,
2949 rhs: Meaning,
2950 ) -> Option<EngineError> {
2951 let value = create_value(1, 1).with_meaning(lhs);
2952 let result = value.apply_meaning(rhs);
2953 result.err().and_then(get_engine_error)
2954 }
2955
2956 fn perform_unary_ok(
2957 function: fn(ValueRef) -> MyResult<ValueRef>,
2958 meaning: Meaning,
2959 ) -> Option<Meaning> {
2960 let value = create_value(1, 1).with_meaning(meaning);
2961 let value = Rc::new(RefCell::new(value));
2962 let result = function(value);
2963 result.ok().map(get_meaning_only)
2964 }
2965
2966 fn perform_unary_err(
2967 function: fn(ValueRef) -> MyResult<ValueRef>,
2968 meaning: Meaning,
2969 ) -> Option<EngineError> {
2970 let value = create_value(1, 1).with_meaning(meaning);
2971 let value = Rc::new(RefCell::new(value));
2972 let result = function(value);
2973 result.err().and_then(get_engine_error)
2974 }
2975
2976 fn perform_binary_ok(
2977 function: fn(ValueRef, ValueRef) -> MyResult<ValueRef>,
2978 lhs: Meaning,
2979 rhs: Meaning,
2980 ) -> Option<Meaning> {
2981 let lhs = create_value(1, 1).with_meaning(lhs);
2982 let rhs = create_value(1, 1).with_meaning(rhs);
2983 let lhs = Rc::new(RefCell::new(lhs));
2984 let rhs = Rc::new(RefCell::new(rhs));
2985 let result = function(lhs, rhs);
2986 result.ok().map(get_meaning_only)
2987 }
2988
2989 fn perform_binary_value(
2990 function: fn(ValueRef, ValueRef) -> MyResult<ValueRef>,
2991 lhs: Meaning,
2992 rhs: Meaning,
2993 ) -> Option<(Meaning, String)> {
2994 let lhs = create_value(1, 1).with_meaning(lhs);
2995 let rhs = create_value(1, 1).with_meaning(rhs);
2996 let lhs = Rc::new(RefCell::new(lhs));
2997 let rhs = Rc::new(RefCell::new(rhs));
2998 let result = function(lhs, rhs);
2999 result.ok().map(get_meaning_value)
3000 }
3001
3002 fn perform_binary_err(
3003 function: fn(ValueRef, ValueRef) -> MyResult<ValueRef>,
3004 lhs: Meaning,
3005 rhs: Meaning,
3006 ) -> Option<EngineError> {
3007 let lhs = create_value(1, 1).with_meaning(lhs);
3008 let rhs = create_value(1, 1).with_meaning(rhs);
3009 let lhs = Rc::new(RefCell::new(lhs));
3010 let rhs = Rc::new(RefCell::new(rhs));
3011 let result = function(lhs, rhs);
3012 result.err().and_then(get_engine_error)
3013 }
3014
3015 fn get_meaning_only(value: ValueRef) -> Meaning {
3016 value.borrow().meaning
3017 }
3018
3019 fn get_meaning_value(value: ValueRef) -> (Meaning, String) {
3020 let context = Context::new().with_dp(Some(9));
3021 let (integer, fraction, _, _, _) = value.borrow().to_strings(&context);
3022 let fraction = truncate_fraction(fraction);
3023 (value.borrow().meaning, format!("{}{}", integer, fraction))
3024 }
3025
3026 fn get_engine_error(error: MyError) -> Option<EngineError> {
3027 match error {
3028 MyError::Engine(error) => Some(error),
3029 _ => None,
3030 }
3031 }
3032
3033 #[test]
3034 fn test_fraction_is_truncated() {
3035 assert_eq!(truncate_fraction(String::from(".000")), String::from(".000"));
3036 assert_eq!(truncate_fraction(String::from(".010")), String::from(".010"));
3037 assert_eq!(truncate_fraction(String::from(".012")), String::from(".012"));
3038 assert_eq!(truncate_fraction(String::from(".000000000")), String::from(".0"));
3039 assert_eq!(truncate_fraction(String::from(".010000000")), String::from(".01"));
3040 assert_eq!(truncate_fraction(String::from(".012000000")), String::from(".012"));
3041 assert_eq!(truncate_fraction(String::from(".012300000")), String::from(".0123"));
3042 assert_eq!(truncate_fraction(String::from(".012340000")), String::from(".01234"));
3043 assert_eq!(truncate_fraction(String::from(".012345000")), String::from(".012345"));
3044 assert_eq!(truncate_fraction(String::from(".012345600")), String::from(".0123456"));
3045 assert_eq!(truncate_fraction(String::from(".012345670")), String::from(".01234567"));
3046 assert_eq!(truncate_fraction(String::from(".012345678")), String::from(".012345678"));
3047 }
3048
3049 fn truncate_fraction(fraction: String) -> String {
3050 let regex = regex!(r"^\.([0-9]*[1-9]|0+?)0+$");
3051 if fraction.len() > 4 {
3052 regex.replace(&fraction, ".$1").to_string()
3053 } else {
3054 fraction
3055 }
3056 }
3057}