rpn_cli/calc/
value.rs

1use crate::calc::context::{Context, Format};
2use crate::calc::meaning::Meaning;
3use crate::error::MyResult;
4use crate::regex;
5use crate::util::text::{create_padding, remove_char};
6use big_rational_str::BigRationalExt;
7use chrono::{DateTime, Duration, NaiveDateTime};
8use itertools::Itertools;
9use num::traits::Inv;
10use num::*;
11use regex::{Captures, Match};
12use std::cell::RefCell;
13use std::cmp::Ordering;
14use std::fmt::{Debug, Formatter};
15use std::iter::zip;
16use std::ops::{BitAnd, BitOr, BitXor, Div, Mul, Sub};
17use std::rc::Rc;
18use std::time::SystemTime;
19
20pub type ValueRef = Rc<RefCell<Value>>;
21
22#[derive(PartialEq)]
23pub struct Value {
24    pub number: Option<BigRational>,
25    pub meaning: Meaning,
26    pub variable: Option<String>,
27    pub comment: Option<String>,
28}
29
30const CHUNK_DIGITS: usize = 8;
31const CHUNK_VALUE: usize = 0x1_0000_0000;
32const ROUNDING_LIMIT: usize = 6;
33
34// noinspection RsLift
35impl Value {
36    pub const fn new(number: Option<BigRational>) -> Self {
37        Self {
38            number,
39            meaning: Meaning::Plain,
40            variable: None,
41            comment: None,
42        }
43    }
44
45    pub fn with_meaning(mut self, meaning: Meaning) -> Self {
46        self.meaning = meaning;
47        self
48    }
49
50    pub fn set_meaning(&mut self, meaning: Meaning) {
51        self.meaning = meaning;
52    }
53
54    pub fn with_variable(mut self, variable: &str) -> Self {
55        self.variable = Some(String::from(variable));
56        self
57    }
58
59    pub fn set_variable(&mut self, variable: &str) {
60        self.variable = Some(String::from(variable));
61    }
62
63    pub fn with_comment(mut self, comment: &str) -> Self {
64        self.comment = Some(String::from(comment));
65        self
66    }
67
68    pub fn set_comment(&mut self, comment: &str) {
69        self.comment = Some(String::from(comment));
70    }
71
72    fn with_rounding(mut self) -> Self {
73        if let Some(number) = &self.number {
74            if let Some(multiplier) = Self::measure_multiplier(number) {
75                if let Some(number) = number.checked_mul(&multiplier) {
76                    let number = number.round();
77                    if let Some(number) = number.checked_div(&multiplier) {
78                        self.number = Some(number);
79                    }
80                }
81            }
82        }
83        self
84    }
85
86    fn measure_multiplier(number: &BigRational) -> Option<BigRational> {
87        let string = big_rational_str::big_rational_ref_to_string(number);
88        if let Some(period) = string.find('.') {
89            let string = remove_char(&string, period);
90            for offset in 1..=ROUNDING_LIMIT {
91                if let Some((start, count)) = Self::measure_offset(&string, offset) {
92                    if let Some(start) = start.checked_sub(period) {
93                        if let Some(remain) = string.len().checked_sub(start + count) {
94                            if remain >= count * 2 {
95                                let multiplier = BigInt::from(10)
96                                    .pow(start as u32);
97                                let multiplier = BigInt::from(10)
98                                    .pow(offset as u32)
99                                    .sub(&BigInt::from(1))
100                                    .mul(&multiplier);
101                                return Some(BigRational::from_integer(multiplier));
102                            }
103                        }
104                    }
105                }
106            }
107        }
108        None
109    }
110
111    // Span:      <------->
112    // Left:  19994564564564564832246034753933155512726838401327...
113    // Right: 94564564564564832246034753933155512726838401327630...
114
115    fn measure_offset(string: &str, offset: usize) -> Option<(usize, usize)> {
116        let left = string.chars();
117        let right = string.chars().skip(offset);
118        let mut span = None;
119        for (index, (left, right)) in zip(left, right).enumerate() {
120            if let Some((start, count)) = span {
121                if left == right {
122                    span = Some((start, count + 1));
123                } else if count >= ROUNDING_LIMIT {
124                    return span;
125                } else {
126                    span = None;
127                }
128            } else {
129                if left == right {
130                    span = Some((index, 0));
131                }
132            }
133        }
134        None
135    }
136
137    pub fn from_string(number: &str) -> MyResult<Self> {
138        if number.starts_with("0x") || number.starts_with("0X") {
139            Self::from_hexadecimal(&number[2..])
140        } else if let Some(value) = Self::from_time(number) {
141            Ok(value)
142        } else if let Some(value) = Self::from_delta(number) {
143            Ok(value)
144        } else if let Some(number) = number.strip_prefix(".") {
145            let number = format!("0.{}", number);
146            Self::from_decimal(&number)
147        } else if let Some(number) = number.strip_prefix("-.") {
148            let number = format!("-0.{}", number);
149            Self::from_decimal(&number)
150        } else {
151            Self::from_decimal(number)
152        }
153    }
154
155    fn from_time(time: &str) -> Option<Self> {
156        if let Some(time) = Self::parse_time(time) {
157            let numer = time.and_utc().timestamp_millis();
158            let numer = BigInt::from(numer);
159            let denom = BigInt::from(1000);
160            let number = BigRational::new(numer, denom);
161            let value = Self::new(Some(number)).with_meaning(Meaning::Time);
162            return Some(value);
163        }
164        None
165    }
166
167    fn parse_time(time: &str) -> Option<NaiveDateTime> {
168        let regex = regex!(r#"^(\d+-\d+-\d+T\d+:\d+(:\d+(\.\d+)?)?)Z?$"#);
169        if let Some(captures) = regex.captures(time) {
170            let time = captures.get(1).as_ref().map(Match::as_str).unwrap_or_default();
171            let format = if captures.get(2).is_none() {
172                "%Y-%m-%dT%H:%M"
173            } else if captures.get(3).is_none() {
174                "%Y-%m-%dT%H:%M:%S"
175            } else {
176                "%Y-%m-%dT%H:%M:%S%.f" // "%.f" not ".%f"
177            };
178            return NaiveDateTime::parse_from_str(time, format).ok();
179        }
180        None
181    }
182
183    fn from_delta(delta: &str) -> Option<Self> {
184        if let Some(delta) = Self::parse_delta(delta) {
185            let numer = delta.num_milliseconds();
186            let numer = BigInt::from(numer);
187            let denom = BigInt::from(1000);
188            let number = BigRational::new(numer, denom);
189            let value = Self::new(Some(number)).with_meaning(Meaning::Delta);
190            return Some(value);
191        }
192        None
193    }
194
195    fn parse_delta(delta: &str) -> Option<Duration> {
196        let regex = regex!(r#"^(-)?(?:(?:(\d+)[T:])?(\d+):)?(\d+):(\d+)(?:\.(\d+))?$"#);
197        if let Some(captures) = regex.captures(delta) {
198            let negative = captures.get(1).is_some();
199            let days = Self::parse_capture(&captures, 2, None);
200            let hours = Self::parse_capture(&captures, 3, None) + (days * 24);
201            let minutes = Self::parse_capture(&captures, 4, None) + (hours * 60);
202            let seconds = Self::parse_capture(&captures, 5, None) + (minutes * 60);
203            let nanos = Self::parse_capture(&captures, 6, Some(9)) + (seconds * 1_000_000_000);
204            let delta = Duration::nanoseconds(nanos);
205            let delta = if negative { -delta } else { delta };
206            return Some(delta);
207        }
208        None
209    }
210
211    fn parse_capture(captures: &Captures, index: usize, expected: Option<usize>) -> i64 {
212        if let Some(capture) = captures.get(index) {
213            let number = capture.as_str().parse::<i64>().unwrap_or_default();
214            if let Some(expected) = expected {
215                let length = capture.as_str().len();
216                if let Some(diff) = expected.checked_sub(length) {
217                    return number * pow(10, diff);
218                }
219                if let Some(diff) = length.checked_sub(expected) {
220                    return number / pow(10, diff);
221                }
222            }
223            return number;
224        }
225        0
226    }
227
228    fn from_decimal(number: &str) -> MyResult<Self> {
229        let number = number.replace(&[',', '_'], "");
230        let number = BigRational::from_dec_str(&number)?;
231        let value = Self::new(Some(number));
232        Ok(value)
233    }
234
235    fn from_hexadecimal(number: &str) -> MyResult<Self> {
236        let number = number.replace(&[',', '_'], "");
237        let number = BigInt::from_str_radix(&number, 16)?;
238        let number = BigRational::from_integer(number);
239        let value = Self::new(Some(number));
240        Ok(value)
241    }
242
243    pub fn to_strings(&self, context: &Context) -> (String, String, Option<String>, Option<String>) {
244        if let Some(number) = &self.number {
245            self.format_ratio(context, number)
246        } else {
247            (String::from("NaN"), String::from(""), self.variable.clone(), self.comment.clone())
248        }
249    }
250
251    fn format_ratio(
252        &self,
253        context: &Context,
254        number: &BigRational,
255    ) -> (String, String, Option<String>, Option<String>) {
256        if self.meaning == Meaning::Time {
257            let number = number * BigInt::from(1000);
258            let number = number.to_i64().unwrap_or_default();
259            let number = Self::format_time(number);
260            self.format_split(context, number)
261        } else if self.meaning == Meaning::Delta {
262            let number = number * BigInt::from(1000);
263            let number = number.to_i64().unwrap_or_default();
264            let number = Self::format_delta(number);
265            self.format_split(context, number)
266        } else if let Format::Base16(chunks) = context.format {
267            let number = number.to_integer();
268            let number = Self::format_hexadecimal(number, chunks, context.sep);
269            (number, String::from(""), self.variable.clone(), self.comment.clone())
270        } else if let Some(dp) = context.dp {
271            let power = BigInt::from(10).pow(dp as u32);
272            let number = number.mul(&power).round().div(&power);
273            let number = big_rational_str::big_rational_to_string(number);
274            self.format_split(context, number)
275        } else {
276            let number = big_rational_str::big_rational_ref_to_string(number);
277            self.format_split(context, number)
278        }
279    }
280
281    fn format_time(millis: i64) -> String {
282        let time = DateTime::from_timestamp_millis(millis).unwrap_or_default();
283        time.format("%Y-%m-%dT%H:%M:%S%.3fZ").to_string()
284    }
285
286    fn format_delta(millis: i64) -> String {
287        let (minus, millis) = (if millis < 0 { "-" } else { "" }, abs(millis));
288        let (seconds, millis) = (millis / 1000, millis % 1000);
289        let (minutes, seconds) = (seconds / 60, seconds % 60);
290        let (hours, minutes) = (minutes / 60, minutes % 60);
291        let (days, hours) = (hours / 24, hours % 24);
292        if days != 0 {
293            format!("{}{}T{:02}:{:02}:{:02}.{:03}", minus, days, hours, minutes, seconds, millis)
294        } else if hours != 0 {
295            format!("{}{:02}:{:02}:{:02}.{:03}", minus, hours, minutes, seconds, millis)
296        } else if minutes != 0 {
297            format!("{}{:02}:{:02}.{:03}", minus, minutes, seconds, millis)
298        } else {
299            format!("{}{:02}.{:03}", minus, seconds, millis)
300        }
301    }
302
303    fn format_hexadecimal(
304        mut number: BigInt,
305        chunks: usize,
306        sep: bool,
307    ) -> String {
308        if number.is_negative() {
309            let range = BigInt::from(CHUNK_VALUE).pow(chunks as u32);
310            number += range;
311        }
312        let number = format!("{:x}", number);
313        let padding = create_padding('0', chunks * CHUNK_DIGITS, number.len(), 0);
314        if sep {
315            let number = format!("{}{}", padding, number);
316            let chunks = number.as_bytes()
317                .chunks(CHUNK_DIGITS)
318                .map(std::str::from_utf8);
319            std::iter::once(Ok("0x"))
320                .chain(chunks)
321                .collect::<Result<Vec<&str>, _>>()
322                .unwrap_or_default()
323                .join(",")
324        } else {
325            format!("0x{}{}", padding, number)
326        }
327    }
328
329    fn format_split(
330        &self,
331        context: &Context,
332        number: String,
333    ) -> (String, String, Option<String>, Option<String>) {
334        let index = number.find('.').unwrap_or(number.len());
335        let (integer, fraction) = number.split_at(index);
336        let integer = self.modify_integer(context, integer);
337        let fraction = self.modify_fraction(context, fraction);
338        (integer, fraction, self.variable.clone(), self.comment.clone())
339    }
340
341    fn modify_integer(&self, context: &Context, number: &str) -> String {
342        if self.meaning == Meaning::Plain && context.sep {
343            let index = if number.starts_with('-') { 1 } else { 0 };
344            let (sign, number) = number.split_at(index);
345            let number = number.as_bytes()
346                .rchunks(3)
347                .rev()
348                .map(std::str::from_utf8)
349                .collect::<Result<Vec<&str>, _>>()
350                .unwrap_or_default()
351                .join(",");
352            return format!("{}{}", sign, number);
353        }
354        String::from(number)
355    }
356
357    fn modify_fraction(&self, context: &Context, number: &str) -> String {
358        if self.meaning == Meaning::Plain {
359            if let Some(dp) = context.dp {
360                if !number.is_empty() || dp > 0 {
361                    let index = if number.starts_with('.') { 1 } else { 0 };
362                    let number = &number[index..];
363                    let dp = dp as usize;
364                    return ".".chars()
365                        .chain(number.chars().take(dp))
366                        .chain(std::iter::repeat('0'))
367                        .take(dp + 1)
368                        .collect::<String>();
369                }
370            }
371        }
372        String::from(number)
373    }
374
375    pub fn measure_hexadecimal(&self) -> usize {
376        if let Some(number) = &self.number {
377            let number = number.to_integer();
378            Self::count_hexadecimal(number)
379        } else {
380            1
381        }
382    }
383
384    fn count_hexadecimal(mut number: BigInt) -> usize {
385        if number.is_negative() {
386            number = number.abs() - 1;
387        }
388        let count = number.iter_u32_digits().count().max(1);
389        let chunk = number.iter_u32_digits().last().unwrap_or_default();
390        if chunk & 0x80000000 != 0 { count + 1 } else { count }
391    }
392
393    fn perform_unary(
394        value: ValueRef,
395        meaning: Meaning,
396        function: fn(&BigRational) -> Option<BigRational>,
397    ) -> ValueRef {
398        if let Some(number) = &value.borrow().number {
399            let result = Self::new(function(number)).with_rounding().with_meaning(meaning);
400            return Rc::new(RefCell::new(result));
401        }
402        value
403    }
404
405    fn perform_binary(
406        lhs: ValueRef,
407        rhs: ValueRef,
408        meaning: Meaning,
409        function: fn(&BigRational, &BigRational) -> Option<BigRational>,
410    ) -> ValueRef {
411        if let Some(lhs) = &lhs.borrow().number {
412            if let Some(rhs) = &rhs.borrow().number {
413                let result = Self::new(function(lhs, rhs)).with_rounding().with_meaning(meaning);
414                return Rc::new(RefCell::new(result));
415            }
416            return rhs;
417        }
418        lhs
419    }
420
421    //       | Plain Delta Time
422    // ------+------------------
423    // Plain | Plain Delta Time
424    // Delta | Delta Delta Time
425    // Time  | Time  Time    -
426
427    pub fn calc_add(lhs: ValueRef, rhs: ValueRef) -> MyResult<ValueRef> {
428        let meaning = lhs.borrow().meaning.combine(rhs.borrow().meaning, Meaning::pdt, Meaning::ddt, Meaning::ttx)?;
429        let result = Self::perform_binary(lhs, rhs, meaning, |x, y| x.checked_add(&y));
430        Ok(result)
431    }
432
433    //       | Plain Delta Time
434    // ------+------------------
435    // Plain | Plain Delta   -
436    // Delta | Delta Delta   -
437    // Time  | Time  Time  Delta
438
439    pub fn calc_sub(lhs: ValueRef, rhs: ValueRef) -> MyResult<ValueRef> {
440        let meaning = lhs.borrow().meaning.combine(rhs.borrow().meaning, Meaning::pdx, Meaning::ddx, Meaning::ttd)?;
441        let result = Self::perform_binary(lhs, rhs, meaning, |x, y| x.checked_sub(&y));
442        Ok(result)
443    }
444
445    //       | Plain Delta Time
446    // ------+------------------
447    // Plain | Plain Delta   -
448    // Delta | Delta   -     -
449    // Time  |   -     -     -
450
451    pub fn calc_mul(lhs: ValueRef, rhs: ValueRef) -> MyResult<ValueRef> {
452        let meaning = lhs.borrow().meaning.combine(rhs.borrow().meaning, Meaning::pdx, Meaning::dxx, Meaning::xxx)?;
453        let result = Self::perform_binary(lhs, rhs, meaning, |x, y| x.checked_mul(&y));
454        Ok(result)
455    }
456
457    //       | Plain Delta Time
458    // ------+------------------
459    // Plain | Plain   -     -
460    // Delta | Delta   -     -
461    // Time  |   -     -     -
462
463    pub fn calc_div(lhs: ValueRef, rhs: ValueRef) -> MyResult<ValueRef> {
464        let meaning = lhs.borrow().meaning.combine(rhs.borrow().meaning, Meaning::pxx, Meaning::dxx, Meaning::xxx)?;
465        let result = Self::perform_binary(lhs, rhs, meaning, |x, y| x.checked_div(&y));
466        Ok(result)
467    }
468
469    pub fn calc_mod(lhs: ValueRef, rhs: ValueRef) -> MyResult<ValueRef> {
470        let meaning = lhs.borrow().meaning.combine(rhs.borrow().meaning, Meaning::pxx, Meaning::dxx, Meaning::xxx)?;
471        let result = Self::perform_binary(lhs, rhs, meaning, Self::checked_mod);
472        Ok(result)
473    }
474
475    fn checked_mod(lhs: &BigRational, rhs: &BigRational) -> Option<BigRational> {
476        lhs.checked_div(rhs)
477            .map(|result| &result - result.to_integer())
478            .map(|result| result * rhs)
479    }
480
481    // Plain | Plain
482    // Delta | Delta
483    // Time  |   -
484
485    pub fn calc_neg(value: ValueRef) -> MyResult<ValueRef> {
486        let meaning = value.borrow().meaning.pdx()?;
487        let result = Self::perform_unary(value, meaning, |x| Some(-x));
488        Ok(result)
489    }
490
491    // Plain | Plain
492    // Delta |   -
493    // Time  |   -
494
495    pub fn calc_inv(value: ValueRef) -> MyResult<ValueRef> {
496        let meaning = value.borrow().meaning.pxx()?;
497        let result = Self::perform_unary(value, meaning, Self::checked_inv);
498        Ok(result)
499    }
500
501    fn checked_inv(number: &BigRational) -> Option<BigRational> {
502        if number.is_zero() { None } else { Some(number.inv()) }
503    }
504
505    //       | Plain Delta Time
506    // ------+------------------
507    // Plain | Plain   -     -
508    // Delta |   -     -     -
509    // Time  |   -     -     -
510
511    pub fn calc_pow(lhs: ValueRef, rhs: ValueRef) -> MyResult<ValueRef> {
512        let meaning = lhs.borrow().meaning.combine(rhs.borrow().meaning, Meaning::pxx, Meaning::xxx, Meaning::xxx)?;
513        let result = Self::perform_binary(lhs, rhs, meaning, Self::checked_pow);
514        Ok(result)
515    }
516
517    fn checked_pow(lhs: &BigRational, rhs: &BigRational) -> Option<BigRational> {
518        if rhs.is_integer() {
519            if let Some(rhs) = rhs.to_i32() {
520                return Some(lhs.pow(rhs));
521            }
522        } else {
523            if let Some(lhs) = lhs.to_f64() {
524                if let Some(rhs) = rhs.to_f64() {
525                    let result = f64::powf(lhs, rhs);
526                    return BigRational::from_f64(result);
527                }
528            }
529        }
530        None
531    }
532
533    // Plain | Plain
534    // Delta |   -
535    // Time  |   -
536
537    pub fn calc_sqrt(value: ValueRef) -> MyResult<ValueRef> {
538        let meaning = value.borrow().meaning.pxx()?;
539        let result = Self::perform_unary(value, meaning, Self::checked_sqrt);
540        Ok(result)
541    }
542
543    fn checked_sqrt(number: &BigRational) -> Option<BigRational> {
544        if let Some(number) = number.to_f64() {
545            let result = number.sqrt();
546            return BigRational::from_f64(result);
547        }
548        None
549    }
550
551    pub fn calc_sum(values: Vec<ValueRef>) -> MyResult<ValueRef> {
552        let mut result = BigRational::from(BigInt::zero());
553        for value in values {
554            if let Some(number) = &value.borrow().number {
555                result += number;
556            }
557        }
558        let result = Self::new(Some(result)).with_rounding();
559        Ok(Rc::new(RefCell::new(result)))
560    }
561
562    pub fn calc_prod(values: Vec<ValueRef>) -> MyResult<ValueRef> {
563        let mut result = BigRational::from(BigInt::one());
564        for value in values {
565            if let Some(number) = &value.borrow().number {
566                result *= number;
567            }
568        }
569        let result = Self::new(Some(result)).with_rounding();
570        Ok(Rc::new(RefCell::new(result)))
571    }
572
573    pub fn calc_seq(start: ValueRef, stop: ValueRef) -> MyResult<Vec<ValueRef>> {
574        let mut values = Vec::new();
575        let meaning = start.borrow().meaning;
576        if let Some(start) = &start.borrow().number {
577            if let Some(stop) = &stop.borrow().number {
578                let step = BigRational::one();
579                Self::inner_step(&mut values, meaning, start, &step, stop);
580            }
581        }
582        Ok(values)
583    }
584
585    pub fn calc_step(start: ValueRef, step: ValueRef, stop: ValueRef) -> MyResult<Vec<ValueRef>> {
586        let mut values = Vec::new();
587        let meaning = start.borrow().meaning;
588        if let Some(start) = &start.borrow().number {
589            if let Some(step) = &step.borrow().number {
590                if let Some(stop) = &stop.borrow().number {
591                    let step = step.abs();
592                    Self::inner_step(&mut values, meaning, start, &step, stop);
593                }
594            }
595        }
596        Ok(values)
597    }
598
599    fn inner_step(
600        values: &mut Vec<ValueRef>,
601        meaning: Meaning,
602        start: &BigRational,
603        step: &BigRational,
604        stop: &BigRational,
605    ) {
606        let mut number = start.clone();
607        Self::inner_push(values, meaning, &number);
608        if step.is_positive() {
609            if number <= *stop {
610                loop {
611                    number += step;
612                    if number > *stop { break }
613                    Self::inner_push(values, meaning, &number);
614                }
615            } else {
616                loop {
617                    number -= step;
618                    if number < *stop { break }
619                    Self::inner_push(values, meaning, &number);
620                }
621            }
622        }
623    }
624
625    fn inner_push(
626        values: &mut Vec<ValueRef>,
627        meaning: Meaning,
628        number: &BigRational,
629    ) {
630        let number = number.clone();
631        let value = Self::new(Some(number)).with_meaning(meaning);
632        values.push(Rc::new(RefCell::new(value)));
633    }
634
635    pub fn sort_seq(values: Vec<ValueRef>) -> MyResult<Vec<ValueRef>> {
636        let results = values.into_iter().sorted_by(Self::cmp_values).collect();
637        Ok(results)
638    }
639
640    pub fn rev_seq(values: Vec<ValueRef>) -> MyResult<Vec<ValueRef>> {
641        let results = values.into_iter().rev().collect();
642        Ok(results)
643    }
644
645    fn cmp_values(lhs: &ValueRef, rhs: &ValueRef) -> Ordering {
646        let lhs = &lhs.borrow().number;
647        let rhs = &rhs.borrow().number;
648        match (lhs, rhs) {
649            (Some(lhs), Some(rhs)) => BigRational::cmp(lhs, rhs),
650            (Some(_), None) => Ordering::Greater,
651            (None, Some(_)) => Ordering::Less,
652            (None, None) => Ordering::Equal,
653        }
654    }
655
656    //       | Plain Delta Time
657    // ------+------------------
658    // Plain | Plain   -     -
659    // Delta |   -     -     -
660    // Time  |   -     -     -
661
662    pub fn calc_and(lhs: ValueRef, rhs: ValueRef) -> MyResult<ValueRef> {
663        let meaning = lhs.borrow().meaning.combine(rhs.borrow().meaning, Meaning::pxx, Meaning::xxx, Meaning::xxx)?;
664        let result = Self::perform_binary(lhs, rhs, meaning, Self::checked_and);
665        Ok(result)
666    }
667
668    pub fn calc_or(lhs: ValueRef, rhs: ValueRef) -> MyResult<ValueRef> {
669        let meaning = lhs.borrow().meaning.combine(rhs.borrow().meaning, Meaning::pxx, Meaning::xxx, Meaning::xxx)?;
670        let result = Self::perform_binary(lhs, rhs, meaning, Self::checked_or);
671        Ok(result)
672    }
673
674    pub fn calc_xor(lhs: ValueRef, rhs: ValueRef) -> MyResult<ValueRef> {
675        let meaning = lhs.borrow().meaning.combine(rhs.borrow().meaning, Meaning::pxx, Meaning::xxx, Meaning::xxx)?;
676        let result = Self::perform_binary(lhs, rhs, meaning, Self::checked_xor);
677        Ok(result)
678    }
679
680    fn checked_and(lhs: &BigRational, rhs: &BigRational) -> Option<BigRational> {
681        let lhs = lhs.to_integer();
682        let rhs = rhs.to_integer();
683        let result = lhs.bitand(rhs);
684        Some(BigRational::from(result))
685    }
686
687    fn checked_or(lhs: &BigRational, rhs: &BigRational) -> Option<BigRational> {
688        let lhs = lhs.to_integer();
689        let rhs = rhs.to_integer();
690        let result = lhs.bitor(rhs);
691        Some(BigRational::from(result))
692    }
693
694    fn checked_xor(lhs: &BigRational, rhs: &BigRational) -> Option<BigRational> {
695        let lhs = lhs.to_integer();
696        let rhs = rhs.to_integer();
697        let result = lhs.bitxor(rhs);
698        Some(BigRational::from(result))
699    }
700
701    pub fn calc_shl(lhs: ValueRef, rhs: ValueRef) -> MyResult<ValueRef> {
702        let meaning = lhs.borrow().meaning.combine(rhs.borrow().meaning, Meaning::pxx, Meaning::xxx, Meaning::xxx)?;
703        let result = Self::perform_binary(lhs, rhs, meaning, |x, y| Self::checked_shl(x, y));
704        Ok(result)
705    }
706
707    pub fn calc_shr(lhs: ValueRef, rhs: ValueRef) -> MyResult<ValueRef> {
708        let meaning = lhs.borrow().meaning.combine(rhs.borrow().meaning, Meaning::pxx, Meaning::xxx, Meaning::xxx)?;
709        let result = Self::perform_binary(lhs, rhs, meaning, |x, y| Self::checked_shr(x, y));
710        Ok(result)
711    }
712
713    fn checked_shl(lhs: &BigRational, rhs: &BigRational) -> Option<BigRational> {
714        if let Some(rhs) = rhs.to_i32() {
715            let two = BigRational::new(BigInt::from(2), BigInt::from(1));
716            Some(lhs * two.pow(rhs))
717        } else {
718            None
719        }
720    }
721
722    fn checked_shr(lhs: &BigRational, rhs: &BigRational) -> Option<BigRational> {
723        if let Some(rhs) = rhs.to_i32() {
724            let two = BigRational::new(BigInt::from(2), BigInt::from(1));
725            Some(lhs * two.pow(-rhs))
726        } else {
727            None
728        }
729    }
730
731    pub fn calc_now(time: &Option<SystemTime>) -> MyResult<ValueRef> {
732        let time = time.unwrap_or_else(SystemTime::now)
733            .duration_since(SystemTime::UNIX_EPOCH)
734            .unwrap_or_default()
735            .as_millis();
736        let numer = BigInt::from(time);
737        let denom = BigInt::from(1000);
738        let number = BigRational::new(numer, denom);
739        let result = Self::new(Some(number)).with_meaning(Meaning::Time);
740        Ok(Rc::new(RefCell::new(result)))
741    }
742
743    pub fn cast_plain(value: ValueRef) -> MyResult<ValueRef> {
744        let result = value.borrow().clone().with_meaning(Meaning::Plain);
745        Ok(Rc::new(RefCell::new(result)))
746    }
747
748    pub fn cast_delta(value: ValueRef) -> MyResult<ValueRef> {
749        let result = value.borrow().clone().with_meaning(Meaning::Delta);
750        Ok(Rc::new(RefCell::new(result)))
751    }
752
753    pub fn cast_time(value: ValueRef) -> MyResult<ValueRef> {
754        let result = value.borrow().clone().with_meaning(Meaning::Time);
755        Ok(Rc::new(RefCell::new(result)))
756    }
757}
758
759impl Default for Value {
760    fn default() -> Self {
761        Self::new(Some(BigRational::zero()))
762    }
763}
764
765impl Clone for Value {
766    fn clone(&self) -> Self {
767        // Clone everything but the variable name.
768        let number = self.number.clone();
769        let mut value = Self::new(number);
770        value.meaning = self.meaning;
771        value.comment = self.comment.clone();
772        value
773    }
774}
775
776impl Debug for Value {
777    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
778        if let Some(number) = &self.number {
779            write!(f, "{}", big_rational_str::big_rational_ref_to_string(number))?;
780        } else {
781            write!(f, "NaN")?;
782        }
783        match self.meaning {
784            Meaning::Plain => (),
785            Meaning::Delta => write!(f, " [delta]")?,
786            Meaning::Time => write!(f, " [time]")?,
787        }
788        if let Some(variable) = &self.variable {
789            write!(f, " = {}", variable)?;
790        }
791        if let Some(comment) = &self.comment {
792            write!(f, " # {}", comment)?;
793        }
794        Ok(())
795    }
796}
797
798// noinspection DuplicatedCode
799#[cfg(test)]
800pub mod tests {
801    use crate::calc::context::{Context, Format};
802    use crate::calc::meaning::Meaning;
803    use crate::calc::value::{Value, ValueRef};
804    use crate::error::{EngineError, MyError, MyResult};
805    use crate::regex;
806    use num::{BigInt, BigRational, CheckedMul, CheckedSub, FromPrimitive, ToPrimitive};
807    use pretty_assertions::assert_eq;
808    use regex::Match;
809    use std::cell::RefCell;
810    use std::rc::Rc;
811
812    const VALUE_NAN: Value = Value::new(None);
813
814    #[test]
815    fn test_decimal_is_created_from_string_no_separator() {
816        assert_eq!(create_value(0, 1), Value::from_string("0").unwrap());
817        assert_eq!(create_value(123456789, 1), Value::from_string("123456789").unwrap());
818        assert_eq!(create_value(-123456789, 1), Value::from_string("-123456789").unwrap());
819        assert_eq!(create_value(123456789, 100), Value::from_string("1234567.89").unwrap());
820        assert_eq!(create_value(-123456789, 100), Value::from_string("-1234567.89").unwrap());
821        assert_eq!(create_value(999, 1000), Value::from_string(".999").unwrap());
822        assert_eq!(create_value(-999, 1000), Value::from_string("-.999").unwrap());
823        assert!(Value::from_string("").is_err());
824        assert!(Value::from_string("foo").is_err());
825    }
826
827    #[test]
828    fn test_decimal_is_created_from_string_with_separator() {
829        assert_eq!(create_value(123456789, 1), Value::from_string("123,456,789").unwrap());
830        assert_eq!(create_value(123456789, 1), Value::from_string("123_456_789").unwrap());
831        assert_eq!(create_value(-123456789, 1), Value::from_string("-123,456,789").unwrap());
832        assert_eq!(create_value(-123456789, 1), Value::from_string("-123_456_789").unwrap());
833        assert_eq!(create_value(123456789, 100), Value::from_string("1,234,567.89").unwrap());
834        assert_eq!(create_value(123456789, 100), Value::from_string("1_234_567.89").unwrap());
835        assert_eq!(create_value(-123456789, 100), Value::from_string("-1,234,567.89").unwrap());
836        assert_eq!(create_value(-123456789, 100), Value::from_string("-1_234_567.89").unwrap());
837    }
838
839    #[test]
840    fn test_hexadecimal_is_created_from_lowercase_no_separator() {
841        assert_eq!(create_value(0, 1), Value::from_string("0x0").unwrap());
842        assert_eq!(create_value(0xffff, 1), Value::from_string("0xffff").unwrap());
843        assert_eq!(create_value(0xffffffff, 1), Value::from_string("0xffffffff").unwrap());
844        assert_eq!(create_value(0xffffffffffff, 1), Value::from_string("0xffffffffffff").unwrap());
845        assert_eq!(create_value(0x0123456789abcdef, 1), Value::from_string("0x0123456789abcdef").unwrap());
846        assert!(Value::from_string("0x").is_err());
847        assert!(Value::from_string("0xfoo").is_err());
848    }
849
850    #[test]
851    fn test_hexadecimal_is_created_from_uppercase_no_separator() {
852        assert_eq!(create_value(0, 1), Value::from_string("0X0").unwrap());
853        assert_eq!(create_value(0xffff, 1), Value::from_string("0XFFFF").unwrap());
854        assert_eq!(create_value(0xffffffff, 1), Value::from_string("0XFFFFFFFF").unwrap());
855        assert_eq!(create_value(0xffffffffffff, 1), Value::from_string("0XFFFFFFFFFFFF").unwrap());
856        assert_eq!(create_value(0x0123456789abcdef, 1), Value::from_string("0X0123456789ABCDEF").unwrap());
857        assert!(Value::from_string("0X").is_err());
858        assert!(Value::from_string("0XFOO").is_err());
859    }
860
861    #[test]
862    fn test_hexadecimal_is_created_from_lowercase_with_separator() {
863        assert_eq!(create_value(0, 1), Value::from_string("0x_0").unwrap());
864        assert_eq!(create_value(0xffff, 1), Value::from_string("0x_ffff").unwrap());
865        assert_eq!(create_value(0xffffffff, 1), Value::from_string("0x_ffff_ffff").unwrap());
866        assert_eq!(create_value(0xffffffffffff, 1), Value::from_string("0x,ffff,ffff,ffff").unwrap());
867        assert_eq!(create_value(0x0123456789abcdef, 1), Value::from_string("0x,0123,4567,89ab,cdef").unwrap());
868        assert!(Value::from_string("0x_").is_err());
869        assert!(Value::from_string("0x,foo").is_err());
870    }
871
872    #[test]
873    fn test_hexadecimal_is_created_from_uppercase_with_separator() {
874        assert_eq!(create_value(0, 1), Value::from_string("0X_0").unwrap());
875        assert_eq!(create_value(0xffff, 1), Value::from_string("0X_FFFF").unwrap());
876        assert_eq!(create_value(0xffffffff, 1), Value::from_string("0X_FFFF_FFFF").unwrap());
877        assert_eq!(create_value(0xffffffffffff, 1), Value::from_string("0X,FFFF,FFFF,FFFF").unwrap());
878        assert_eq!(create_value(0x0123456789abcdef, 1), Value::from_string("0X,0123,4567,89AB,CDEF").unwrap());
879        assert!(Value::from_string("0X_").is_err());
880        assert!(Value::from_string("0X,FOO").is_err());
881    }
882
883    #[test]
884    fn test_time_is_created_from_string_no_zulu() {
885        let summer1 = Value::from_string("2024-06-30T23:59").unwrap();
886        let summer2 = Value::from_string("2024-06-30T23:59:59").unwrap();
887        let summer3 = Value::from_string("2024-06-30T23:59:59.999").unwrap();
888        let winter1 = Value::from_string("2024-12-31T23:59").unwrap();
889        let winter2 = Value::from_string("2024-12-31T23:59:59").unwrap();
890        let winter3 = Value::from_string("2024-12-31T23:59:59.999").unwrap();
891        assert_eq!(create_value(1719791940000, 1000).with_meaning(Meaning::Time), summer1);
892        assert_eq!(create_value(1719791999000, 1000).with_meaning(Meaning::Time), summer2);
893        assert_eq!(create_value(1719791999999, 1000).with_meaning(Meaning::Time), summer3);
894        assert_eq!(create_value(1735689540000, 1000).with_meaning(Meaning::Time), winter1);
895        assert_eq!(create_value(1735689599000, 1000).with_meaning(Meaning::Time), winter2);
896        assert_eq!(create_value(1735689599999, 1000).with_meaning(Meaning::Time), winter3);
897    }
898
899    #[test]
900    fn test_time_is_created_from_string_with_zulu() {
901        let summer1 = Value::from_string("2024-06-30T23:59Z").unwrap();
902        let summer2 = Value::from_string("2024-06-30T23:59:59Z").unwrap();
903        let summer3 = Value::from_string("2024-06-30T23:59:59.999Z").unwrap();
904        let winter1 = Value::from_string("2024-12-31T23:59Z").unwrap();
905        let winter2 = Value::from_string("2024-12-31T23:59:59Z").unwrap();
906        let winter3 = Value::from_string("2024-12-31T23:59:59.999Z").unwrap();
907        assert_eq!(create_value(1719791940000, 1000).with_meaning(Meaning::Time), summer1);
908        assert_eq!(create_value(1719791999000, 1000).with_meaning(Meaning::Time), summer2);
909        assert_eq!(create_value(1719791999999, 1000).with_meaning(Meaning::Time), summer3);
910        assert_eq!(create_value(1735689540000, 1000).with_meaning(Meaning::Time), winter1);
911        assert_eq!(create_value(1735689599000, 1000).with_meaning(Meaning::Time), winter2);
912        assert_eq!(create_value(1735689599999, 1000).with_meaning(Meaning::Time), winter3);
913    }
914
915    #[test]
916    fn test_delta_is_created_from_string_old_format() {
917        let minutes1 = Value::from_string("34:56").unwrap();
918        let minutes2 = Value::from_string("34:56.7").unwrap();
919        let minutes3 = Value::from_string("34:56.789").unwrap();
920        let minutes4 = Value::from_string("-34:56").unwrap();
921        let minutes5 = Value::from_string("-34:56.7").unwrap();
922        let minutes6 = Value::from_string("-34:56.789").unwrap();
923        let hours1 = Value::from_string("12:34:56").unwrap();
924        let hours2 = Value::from_string("12:34:56.7").unwrap();
925        let hours3 = Value::from_string("12:34:56.789").unwrap();
926        let hours4 = Value::from_string("-12:34:56").unwrap();
927        let hours5 = Value::from_string("-12:34:56.7").unwrap();
928        let hours6 = Value::from_string("-12:34:56.789").unwrap();
929        let days1 = Value::from_string("9:12:34:56").unwrap();
930        let days2 = Value::from_string("9:12:34:56.7").unwrap();
931        let days3 = Value::from_string("9:12:34:56.789").unwrap();
932        let days4 = Value::from_string("-9:12:34:56").unwrap();
933        let days5 = Value::from_string("-9:12:34:56.7").unwrap();
934        let days6 = Value::from_string("-9:12:34:56.789").unwrap();
935        assert_eq!(create_value(2096000, 1000).with_meaning(Meaning::Delta), minutes1);
936        assert_eq!(create_value(2096700, 1000).with_meaning(Meaning::Delta), minutes2);
937        assert_eq!(create_value(2096789, 1000).with_meaning(Meaning::Delta), minutes3);
938        assert_eq!(create_value(-2096000, 1000).with_meaning(Meaning::Delta), minutes4);
939        assert_eq!(create_value(-2096700, 1000).with_meaning(Meaning::Delta), minutes5);
940        assert_eq!(create_value(-2096789, 1000).with_meaning(Meaning::Delta), minutes6);
941        assert_eq!(create_value(45296000, 1000).with_meaning(Meaning::Delta), hours1);
942        assert_eq!(create_value(45296700, 1000).with_meaning(Meaning::Delta), hours2);
943        assert_eq!(create_value(45296789, 1000).with_meaning(Meaning::Delta), hours3);
944        assert_eq!(create_value(-45296000, 1000).with_meaning(Meaning::Delta), hours4);
945        assert_eq!(create_value(-45296700, 1000).with_meaning(Meaning::Delta), hours5);
946        assert_eq!(create_value(-45296789, 1000).with_meaning(Meaning::Delta), hours6);
947        assert_eq!(create_value(822896000, 1000).with_meaning(Meaning::Delta), days1);
948        assert_eq!(create_value(822896700, 1000).with_meaning(Meaning::Delta), days2);
949        assert_eq!(create_value(822896789, 1000).with_meaning(Meaning::Delta), days3);
950        assert_eq!(create_value(-822896000, 1000).with_meaning(Meaning::Delta), days4);
951        assert_eq!(create_value(-822896700, 1000).with_meaning(Meaning::Delta), days5);
952        assert_eq!(create_value(-822896789, 1000).with_meaning(Meaning::Delta), days6);
953    }
954
955    #[test]
956    fn test_delta_is_created_from_string_new_format() {
957        let days1 = Value::from_string("9T12:34:56").unwrap();
958        let days2 = Value::from_string("9T12:34:56.7").unwrap();
959        let days3 = Value::from_string("9T12:34:56.789").unwrap();
960        let days4 = Value::from_string("-9T12:34:56").unwrap();
961        let days5 = Value::from_string("-9T12:34:56.7").unwrap();
962        let days6 = Value::from_string("-9T12:34:56.789").unwrap();
963        assert_eq!(create_value(822896000, 1000).with_meaning(Meaning::Delta), days1);
964        assert_eq!(create_value(822896700, 1000).with_meaning(Meaning::Delta), days2);
965        assert_eq!(create_value(822896789, 1000).with_meaning(Meaning::Delta), days3);
966        assert_eq!(create_value(-822896000, 1000).with_meaning(Meaning::Delta), days4);
967        assert_eq!(create_value(-822896700, 1000).with_meaning(Meaning::Delta), days5);
968        assert_eq!(create_value(-822896789, 1000).with_meaning(Meaning::Delta), days6);
969    }
970
971    #[test]
972    fn test_value_with_repeating_zero_or_nine_is_rounded() {
973        let number1 = fudge_ratio(create_ratio(17, 8)).and_then(opposite_ratio); // 1.874999999999999801...
974        let number2 = fudge_ratio(create_ratio(16, 8)).and_then(opposite_ratio); // 1.999999999999999726...
975        let number3 = fudge_ratio(create_ratio(16, 8)); // 2.000000000000000273...
976        let number4 = fudge_ratio(create_ratio(17, 8)); // 2.125000000000000198...
977        assert_eq!(create_value(15, 8), Value::new(number1).with_rounding());
978        assert_eq!(create_value(16, 8), Value::new(number2).with_rounding());
979        assert_eq!(create_value(16, 8), Value::new(number3).with_rounding());
980        assert_eq!(create_value(17, 8), Value::new(number4).with_rounding());
981    }
982
983    #[test]
984    fn test_value_with_repeating_one_to_eight_is_rounded() {
985        let number1 = fudge_ratio(create_ratio(908992, 9000)); // 100.999111111111094...
986        let number2 = fudge_ratio(create_ratio(1088924, 99000)); // 10.999232323232323771...
987        let number3 = fudge_ratio(create_ratio(1997457, 999000)); // 1.999456456456456483...
988        let number4 = fudge_ratio(create_ratio(19995891, 9999000)); // 1.999789078907890437...
989        assert_eq!(create_value(908992, 9000), Value::new(number1).with_rounding());
990        assert_eq!(create_value(1088924, 99000), Value::new(number2).with_rounding());
991        assert_eq!(create_value(1997457, 999000), Value::new(number3).with_rounding());
992        assert_eq!(create_value(19995891, 9999000), Value::new(number4).with_rounding());
993    }
994
995    #[test]
996    fn test_decimal_is_formatted_with_default() {
997        let context = Context::new();
998        assert_eq!((String::from("0"), String::from(""), None, None), create_value(0, 1).to_strings(&context));
999        assert_eq!((String::from("1"), String::from(""), None, None), create_value(1, 1).to_strings(&context));
1000        assert_eq!((String::from("12"), String::from(""), None, None), create_value(12, 1).to_strings(&context));
1001        assert_eq!((String::from("123"), String::from(""), None, None), create_value(123, 1).to_strings(&context));
1002        assert_eq!((String::from("1234"), String::from(""), None, None), create_value(1234, 1).to_strings(&context));
1003        assert_eq!((String::from("12345"), String::from(""), None, None), create_value(12345, 1).to_strings(&context));
1004        assert_eq!((String::from("123456"), String::from(""), None, None), create_value(123456, 1).to_strings(&context));
1005        assert_eq!((String::from("1234567"), String::from(""), None, None), create_value(1234567, 1).to_strings(&context));
1006        assert_eq!((String::from("12345678"), String::from(""), None, None), create_value(12345678, 1).to_strings(&context));
1007        assert_eq!((String::from("123456789"), String::from(""), None, None), create_value(123456789, 1).to_strings(&context));
1008        assert_eq!((String::from("-1"), String::from(""), None, None), create_value(-1, 1).to_strings(&context));
1009        assert_eq!((String::from("-12"), String::from(""), None, None), create_value(-12, 1).to_strings(&context));
1010        assert_eq!((String::from("-123"), String::from(""), None, None), create_value(-123, 1).to_strings(&context));
1011        assert_eq!((String::from("-1234"), String::from(""), None, None), create_value(-1234, 1).to_strings(&context));
1012        assert_eq!((String::from("-12345"), String::from(""), None, None), create_value(-12345, 1).to_strings(&context));
1013        assert_eq!((String::from("-123456"), String::from(""), None, None), create_value(-123456, 1).to_strings(&context));
1014        assert_eq!((String::from("-1234567"), String::from(""), None, None), create_value(-1234567, 1).to_strings(&context));
1015        assert_eq!((String::from("-12345678"), String::from(""), None, None), create_value(-12345678, 1).to_strings(&context));
1016        assert_eq!((String::from("-123456789"), String::from(""), None, None), create_value(-123456789, 1).to_strings(&context));
1017        assert_eq!((String::from("0"), String::from(".00001"), None, None), create_value(1, 100000).to_strings(&context));
1018        assert_eq!((String::from("0"), String::from(".0001"), None, None), create_value(1, 10000).to_strings(&context));
1019        assert_eq!((String::from("0"), String::from(".001"), None, None), create_value(1, 1000).to_strings(&context));
1020        assert_eq!((String::from("0"), String::from(".01"), None, None), create_value(1, 100).to_strings(&context));
1021        assert_eq!((String::from("0"), String::from(".1"), None, None), create_value(1, 10).to_strings(&context));
1022        assert_eq!((String::from("0"), String::from(".4994"), None, None), create_value(49940, 100000).to_strings(&context));
1023        assert_eq!((String::from("0"), String::from(".49949"), None, None), create_value(49949, 100000).to_strings(&context));
1024        assert_eq!((String::from("0"), String::from(".4995"), None, None), create_value(49950, 100000).to_strings(&context));
1025        assert_eq!((String::from("0"), String::from(".49951"), None, None), create_value(49951, 100000).to_strings(&context));
1026        assert_eq!((String::from("0"), String::from(".9"), None, None), create_value(9, 10).to_strings(&context));
1027        assert_eq!((String::from("0"), String::from(".99"), None, None), create_value(99, 100).to_strings(&context));
1028        assert_eq!((String::from("0"), String::from(".999"), None, None), create_value(999, 1000).to_strings(&context));
1029        assert_eq!((String::from("0"), String::from(".9999"), None, None), create_value(9999, 10000).to_strings(&context));
1030        assert_eq!((String::from("0"), String::from(".99999"), None, None), create_value(99999, 100000).to_strings(&context));
1031        assert_eq!((String::from("-0"), String::from(".00001"), None, None), create_value(-1, 100000).to_strings(&context));
1032        assert_eq!((String::from("-0"), String::from(".0001"), None, None), create_value(-1, 10000).to_strings(&context));
1033        assert_eq!((String::from("-0"), String::from(".001"), None, None), create_value(-1, 1000).to_strings(&context));
1034        assert_eq!((String::from("-0"), String::from(".01"), None, None), create_value(-1, 100).to_strings(&context));
1035        assert_eq!((String::from("-0"), String::from(".1"), None, None), create_value(-1, 10).to_strings(&context));
1036        assert_eq!((String::from("-0"), String::from(".4994"), None, None), create_value(-49940, 100000).to_strings(&context));
1037        assert_eq!((String::from("-0"), String::from(".49949"), None, None), create_value(-49949, 100000).to_strings(&context));
1038        assert_eq!((String::from("-0"), String::from(".4995"), None, None), create_value(-49950, 100000).to_strings(&context));
1039        assert_eq!((String::from("-0"), String::from(".49951"), None, None), create_value(-49951, 100000).to_strings(&context));
1040        assert_eq!((String::from("-0"), String::from(".9"), None, None), create_value(-9, 10).to_strings(&context));
1041        assert_eq!((String::from("-0"), String::from(".99"), None, None), create_value(-99, 100).to_strings(&context));
1042        assert_eq!((String::from("-0"), String::from(".999"), None, None), create_value(-999, 1000).to_strings(&context));
1043        assert_eq!((String::from("-0"), String::from(".9999"), None, None), create_value(-9999, 10000).to_strings(&context));
1044        assert_eq!((String::from("-0"), String::from(".99999"), None, None), create_value(-99999, 100000).to_strings(&context));
1045    }
1046
1047    #[test]
1048    fn test_decimal_is_formatted_with_separator() {
1049        let context = Context::new().with_sep(true);
1050        assert_eq!((String::from("0"), String::from(""), None, None), create_value(0, 1).to_strings(&context));
1051        assert_eq!((String::from("1"), String::from(""), None, None), create_value(1, 1).to_strings(&context));
1052        assert_eq!((String::from("12"), String::from(""), None, None), create_value(12, 1).to_strings(&context));
1053        assert_eq!((String::from("123"), String::from(""), None, None), create_value(123, 1).to_strings(&context));
1054        assert_eq!((String::from("1,234"), String::from(""), None, None), create_value(1234, 1).to_strings(&context));
1055        assert_eq!((String::from("12,345"), String::from(""), None, None), create_value(12345, 1).to_strings(&context));
1056        assert_eq!((String::from("123,456"), String::from(""), None, None), create_value(123456, 1).to_strings(&context));
1057        assert_eq!((String::from("1,234,567"), String::from(""), None, None), create_value(1234567, 1).to_strings(&context));
1058        assert_eq!((String::from("12,345,678"), String::from(""), None, None), create_value(12345678, 1).to_strings(&context));
1059        assert_eq!((String::from("123,456,789"), String::from(""), None, None), create_value(123456789, 1).to_strings(&context));
1060        assert_eq!((String::from("-1"), String::from(""), None, None), create_value(-1, 1).to_strings(&context));
1061        assert_eq!((String::from("-12"), String::from(""), None, None), create_value(-12, 1).to_strings(&context));
1062        assert_eq!((String::from("-123"), String::from(""), None, None), create_value(-123, 1).to_strings(&context));
1063        assert_eq!((String::from("-1,234"), String::from(""), None, None), create_value(-1234, 1).to_strings(&context));
1064        assert_eq!((String::from("-12,345"), String::from(""), None, None), create_value(-12345, 1).to_strings(&context));
1065        assert_eq!((String::from("-123,456"), String::from(""), None, None), create_value(-123456, 1).to_strings(&context));
1066        assert_eq!((String::from("-1,234,567"), String::from(""), None, None), create_value(-1234567, 1).to_strings(&context));
1067        assert_eq!((String::from("-12,345,678"), String::from(""), None, None), create_value(-12345678, 1).to_strings(&context));
1068        assert_eq!((String::from("-123,456,789"), String::from(""), None, None), create_value(-123456789, 1).to_strings(&context));
1069        assert_eq!((String::from("0"), String::from(".00001"), None, None), create_value(1, 100000).to_strings(&context));
1070        assert_eq!((String::from("0"), String::from(".0001"), None, None), create_value(1, 10000).to_strings(&context));
1071        assert_eq!((String::from("0"), String::from(".001"), None, None), create_value(1, 1000).to_strings(&context));
1072        assert_eq!((String::from("0"), String::from(".01"), None, None), create_value(1, 100).to_strings(&context));
1073        assert_eq!((String::from("0"), String::from(".1"), None, None), create_value(1, 10).to_strings(&context));
1074        assert_eq!((String::from("0"), String::from(".4994"), None, None), create_value(49940, 100000).to_strings(&context));
1075        assert_eq!((String::from("0"), String::from(".49949"), None, None), create_value(49949, 100000).to_strings(&context));
1076        assert_eq!((String::from("0"), String::from(".4995"), None, None), create_value(49950, 100000).to_strings(&context));
1077        assert_eq!((String::from("0"), String::from(".49951"), None, None), create_value(49951, 100000).to_strings(&context));
1078        assert_eq!((String::from("0"), String::from(".9"), None, None), create_value(9, 10).to_strings(&context));
1079        assert_eq!((String::from("0"), String::from(".99"), None, None), create_value(99, 100).to_strings(&context));
1080        assert_eq!((String::from("0"), String::from(".999"), None, None), create_value(999, 1000).to_strings(&context));
1081        assert_eq!((String::from("0"), String::from(".9999"), None, None), create_value(9999, 10000).to_strings(&context));
1082        assert_eq!((String::from("0"), String::from(".99999"), None, None), create_value(99999, 100000).to_strings(&context));
1083        assert_eq!((String::from("-0"), String::from(".00001"), None, None), create_value(-1, 100000).to_strings(&context));
1084        assert_eq!((String::from("-0"), String::from(".0001"), None, None), create_value(-1, 10000).to_strings(&context));
1085        assert_eq!((String::from("-0"), String::from(".001"), None, None), create_value(-1, 1000).to_strings(&context));
1086        assert_eq!((String::from("-0"), String::from(".01"), None, None), create_value(-1, 100).to_strings(&context));
1087        assert_eq!((String::from("-0"), String::from(".1"), None, None), create_value(-1, 10).to_strings(&context));
1088        assert_eq!((String::from("-0"), String::from(".4994"), None, None), create_value(-49940, 100000).to_strings(&context));
1089        assert_eq!((String::from("-0"), String::from(".49949"), None, None), create_value(-49949, 100000).to_strings(&context));
1090        assert_eq!((String::from("-0"), String::from(".4995"), None, None), create_value(-49950, 100000).to_strings(&context));
1091        assert_eq!((String::from("-0"), String::from(".49951"), None, None), create_value(-49951, 100000).to_strings(&context));
1092        assert_eq!((String::from("-0"), String::from(".9"), None, None), create_value(-9, 10).to_strings(&context));
1093        assert_eq!((String::from("-0"), String::from(".99"), None, None), create_value(-99, 100).to_strings(&context));
1094        assert_eq!((String::from("-0"), String::from(".999"), None, None), create_value(-999, 1000).to_strings(&context));
1095        assert_eq!((String::from("-0"), String::from(".9999"), None, None), create_value(-9999, 10000).to_strings(&context));
1096        assert_eq!((String::from("-0"), String::from(".99999"), None, None), create_value(-99999, 100000).to_strings(&context));
1097    }
1098
1099    #[test]
1100    fn test_decimal_is_formatted_with_precision() {
1101        let context = Context::new().with_dp(Some(3));
1102        assert_eq!((String::from("0"), String::from(".000"), None, None), create_value(0, 1).to_strings(&context));
1103        assert_eq!((String::from("1"), String::from(".000"), None, None), create_value(1, 1).to_strings(&context));
1104        assert_eq!((String::from("12"), String::from(".000"), None, None), create_value(12, 1).to_strings(&context));
1105        assert_eq!((String::from("123"), String::from(".000"), None, None), create_value(123, 1).to_strings(&context));
1106        assert_eq!((String::from("1234"), String::from(".000"), None, None), create_value(1234, 1).to_strings(&context));
1107        assert_eq!((String::from("12345"), String::from(".000"), None, None), create_value(12345, 1).to_strings(&context));
1108        assert_eq!((String::from("123456"), String::from(".000"), None, None), create_value(123456, 1).to_strings(&context));
1109        assert_eq!((String::from("1234567"), String::from(".000"), None, None), create_value(1234567, 1).to_strings(&context));
1110        assert_eq!((String::from("12345678"), String::from(".000"), None, None), create_value(12345678, 1).to_strings(&context));
1111        assert_eq!((String::from("123456789"), String::from(".000"), None, None), create_value(123456789, 1).to_strings(&context));
1112        assert_eq!((String::from("-1"), String::from(".000"), None, None), create_value(-1, 1).to_strings(&context));
1113        assert_eq!((String::from("-12"), String::from(".000"), None, None), create_value(-12, 1).to_strings(&context));
1114        assert_eq!((String::from("-123"), String::from(".000"), None, None), create_value(-123, 1).to_strings(&context));
1115        assert_eq!((String::from("-1234"), String::from(".000"), None, None), create_value(-1234, 1).to_strings(&context));
1116        assert_eq!((String::from("-12345"), String::from(".000"), None, None), create_value(-12345, 1).to_strings(&context));
1117        assert_eq!((String::from("-123456"), String::from(".000"), None, None), create_value(-123456, 1).to_strings(&context));
1118        assert_eq!((String::from("-1234567"), String::from(".000"), None, None), create_value(-1234567, 1).to_strings(&context));
1119        assert_eq!((String::from("-12345678"), String::from(".000"), None, None), create_value(-12345678, 1).to_strings(&context));
1120        assert_eq!((String::from("-123456789"), String::from(".000"), None, None), create_value(-123456789, 1).to_strings(&context));
1121        assert_eq!((String::from("0"), String::from(".000"), None, None), create_value(1, 100000).to_strings(&context));
1122        assert_eq!((String::from("0"), String::from(".000"), None, None), create_value(1, 10000).to_strings(&context));
1123        assert_eq!((String::from("0"), String::from(".001"), None, None), create_value(1, 1000).to_strings(&context));
1124        assert_eq!((String::from("0"), String::from(".010"), None, None), create_value(1, 100).to_strings(&context));
1125        assert_eq!((String::from("0"), String::from(".100"), None, None), create_value(1, 10).to_strings(&context));
1126        assert_eq!((String::from("0"), String::from(".499"), None, None), create_value(49940, 100000).to_strings(&context));
1127        assert_eq!((String::from("0"), String::from(".499"), None, None), create_value(49949, 100000).to_strings(&context));
1128        assert_eq!((String::from("0"), String::from(".500"), None, None), create_value(49950, 100000).to_strings(&context));
1129        assert_eq!((String::from("0"), String::from(".500"), None, None), create_value(49951, 100000).to_strings(&context));
1130        assert_eq!((String::from("0"), String::from(".900"), None, None), create_value(9, 10).to_strings(&context));
1131        assert_eq!((String::from("0"), String::from(".990"), None, None), create_value(99, 100).to_strings(&context));
1132        assert_eq!((String::from("0"), String::from(".999"), None, None), create_value(999, 1000).to_strings(&context));
1133        assert_eq!((String::from("1"), String::from(".000"), None, None), create_value(9999, 10000).to_strings(&context));
1134        assert_eq!((String::from("1"), String::from(".000"), None, None), create_value(99999, 100000).to_strings(&context));
1135        assert_eq!((String::from("0"), String::from(".000"), None, None), create_value(-1, 100000).to_strings(&context));
1136        assert_eq!((String::from("0"), String::from(".000"), None, None), create_value(-1, 10000).to_strings(&context));
1137        assert_eq!((String::from("-0"), String::from(".001"), None, None), create_value(-1, 1000).to_strings(&context));
1138        assert_eq!((String::from("-0"), String::from(".010"), None, None), create_value(-1, 100).to_strings(&context));
1139        assert_eq!((String::from("-0"), String::from(".100"), None, None), create_value(-1, 10).to_strings(&context));
1140        assert_eq!((String::from("-0"), String::from(".499"), None, None), create_value(-49940, 100000).to_strings(&context));
1141        assert_eq!((String::from("-0"), String::from(".499"), None, None), create_value(-49949, 100000).to_strings(&context));
1142        assert_eq!((String::from("-0"), String::from(".500"), None, None), create_value(-49950, 100000).to_strings(&context));
1143        assert_eq!((String::from("-0"), String::from(".500"), None, None), create_value(-49951, 100000).to_strings(&context));
1144        assert_eq!((String::from("-0"), String::from(".900"), None, None), create_value(-9, 10).to_strings(&context));
1145        assert_eq!((String::from("-0"), String::from(".990"), None, None), create_value(-99, 100).to_strings(&context));
1146        assert_eq!((String::from("-0"), String::from(".999"), None, None), create_value(-999, 1000).to_strings(&context));
1147        assert_eq!((String::from("-1"), String::from(".000"), None, None), create_value(-9999, 10000).to_strings(&context));
1148        assert_eq!((String::from("-1"), String::from(".000"), None, None), create_value(-99999, 100000).to_strings(&context));
1149    }
1150
1151    #[test]
1152    fn test_recurring_is_formatted_with_precision() {
1153        let value = create_value(1, 3);
1154        let format = |dp: Option<u8>| {
1155            let context = Context::new().with_dp(dp);
1156            let (_, fraction, _, _) = value.to_strings(&context);
1157            return fraction;
1158        };
1159        assert_eq!(String::from(""), format(Some(0)));
1160        assert_eq!(String::from(".333333"), format(Some(6)));
1161        assert_eq!(String::from(".(3)"), format(None));
1162    }
1163
1164    #[test]
1165    fn test_hexadecimal_is_formatted_with_default() {
1166        let context = Context::new().with_format(Format::Base16(3));
1167        assert_eq!((String::from("0x000000000000000000000000"), String::from(""), None, None), create_value(0, 1).to_strings(&context));
1168        assert_eq!((String::from("0x000000000000000000000001"), String::from(""), None, None), create_value(1, 1).to_strings(&context));
1169        assert_eq!((String::from("0x00000000000000007ffffffe"), String::from(""), None, None), create_value(2147483646, 1).to_strings(&context));
1170        assert_eq!((String::from("0x00000000000000007fffffff"), String::from(""), None, None), create_value(2147483647, 1).to_strings(&context));
1171        assert_eq!((String::from("0x000000000000000080000000"), String::from(""), None, None), create_value(2147483648, 1).to_strings(&context));
1172        assert_eq!((String::from("0x000000000000000080000001"), String::from(""), None, None), create_value(2147483649, 1).to_strings(&context));
1173        assert_eq!((String::from("0x0000000000000000fffffffe"), String::from(""), None, None), create_value(4294967294, 1).to_strings(&context));
1174        assert_eq!((String::from("0x0000000000000000ffffffff"), String::from(""), None, None), create_value(4294967295, 1).to_strings(&context));
1175        assert_eq!((String::from("0x000000000000000100000000"), String::from(""), None, None), create_value(4294967296, 1).to_strings(&context));
1176        assert_eq!((String::from("0x000000000000000100000001"), String::from(""), None, None), create_value(4294967297, 1).to_strings(&context));
1177        assert_eq!((String::from("0x000000007ffffffffffffffe"), String::from(""), None, None), create_value(9223372036854775806, 1).to_strings(&context));
1178        assert_eq!((String::from("0x000000007fffffffffffffff"), String::from(""), None, None), create_value(9223372036854775807, 1).to_strings(&context));
1179        assert_eq!((String::from("0x000000008000000000000000"), String::from(""), None, None), create_value(9223372036854775808, 1).to_strings(&context));
1180        assert_eq!((String::from("0x000000008000000000000001"), String::from(""), None, None), create_value(9223372036854775809, 1).to_strings(&context));
1181        assert_eq!((String::from("0x00000000fffffffffffffffe"), String::from(""), None, None), create_value(18446744073709551614, 1).to_strings(&context));
1182        assert_eq!((String::from("0x00000000ffffffffffffffff"), String::from(""), None, None), create_value(18446744073709551615, 1).to_strings(&context));
1183        assert_eq!((String::from("0x000000010000000000000000"), String::from(""), None, None), create_value(18446744073709551616, 1).to_strings(&context));
1184        assert_eq!((String::from("0x000000010000000000000001"), String::from(""), None, None), create_value(18446744073709551617, 1).to_strings(&context));
1185        assert_eq!((String::from("0xffffffff0000000000000000"), String::from(""), None, None), create_value(-18446744073709551616, 1).to_strings(&context));
1186        assert_eq!((String::from("0xffffffff0000000000000001"), String::from(""), None, None), create_value(-18446744073709551615, 1).to_strings(&context));
1187        assert_eq!((String::from("0xffffffff8000000000000000"), String::from(""), None, None), create_value(-9223372036854775808, 1).to_strings(&context));
1188        assert_eq!((String::from("0xffffffff8000000000000001"), String::from(""), None, None), create_value(-9223372036854775807, 1).to_strings(&context));
1189        assert_eq!((String::from("0xffffffffffffffff00000000"), String::from(""), None, None), create_value(-4294967296, 1).to_strings(&context));
1190        assert_eq!((String::from("0xffffffffffffffff00000001"), String::from(""), None, None), create_value(-4294967295, 1).to_strings(&context));
1191        assert_eq!((String::from("0xffffffffffffffff80000000"), String::from(""), None, None), create_value(-2147483648, 1).to_strings(&context));
1192        assert_eq!((String::from("0xffffffffffffffff80000001"), String::from(""), None, None), create_value(-2147483647, 1).to_strings(&context));
1193        assert_eq!((String::from("0xfffffffffffffffffffffffe"), String::from(""), None, None), create_value(-2, 1).to_strings(&context));
1194        assert_eq!((String::from("0xffffffffffffffffffffffff"), String::from(""), None, None), create_value(-1, 1).to_strings(&context));
1195    }
1196
1197    #[test]
1198    fn test_hexadecimal_is_formatted_with_separator() {
1199        let context = Context::new().with_format(Format::Base16(3)).with_sep(true);
1200        assert_eq!((String::from("0x,00000000,00000000,00000000"), String::from(""), None, None), create_value(0, 1).to_strings(&context));
1201        assert_eq!((String::from("0x,00000000,00000000,00000001"), String::from(""), None, None), create_value(1, 1).to_strings(&context));
1202        assert_eq!((String::from("0x,00000000,00000000,7ffffffe"), String::from(""), None, None), create_value(2147483646, 1).to_strings(&context));
1203        assert_eq!((String::from("0x,00000000,00000000,7fffffff"), String::from(""), None, None), create_value(2147483647, 1).to_strings(&context));
1204        assert_eq!((String::from("0x,00000000,00000000,80000000"), String::from(""), None, None), create_value(2147483648, 1).to_strings(&context));
1205        assert_eq!((String::from("0x,00000000,00000000,80000001"), String::from(""), None, None), create_value(2147483649, 1).to_strings(&context));
1206        assert_eq!((String::from("0x,00000000,00000000,fffffffe"), String::from(""), None, None), create_value(4294967294, 1).to_strings(&context));
1207        assert_eq!((String::from("0x,00000000,00000000,ffffffff"), String::from(""), None, None), create_value(4294967295, 1).to_strings(&context));
1208        assert_eq!((String::from("0x,00000000,00000001,00000000"), String::from(""), None, None), create_value(4294967296, 1).to_strings(&context));
1209        assert_eq!((String::from("0x,00000000,00000001,00000001"), String::from(""), None, None), create_value(4294967297, 1).to_strings(&context));
1210        assert_eq!((String::from("0x,00000000,7fffffff,fffffffe"), String::from(""), None, None), create_value(9223372036854775806, 1).to_strings(&context));
1211        assert_eq!((String::from("0x,00000000,7fffffff,ffffffff"), String::from(""), None, None), create_value(9223372036854775807, 1).to_strings(&context));
1212        assert_eq!((String::from("0x,00000000,80000000,00000000"), String::from(""), None, None), create_value(9223372036854775808, 1).to_strings(&context));
1213        assert_eq!((String::from("0x,00000000,80000000,00000001"), String::from(""), None, None), create_value(9223372036854775809, 1).to_strings(&context));
1214        assert_eq!((String::from("0x,00000000,ffffffff,fffffffe"), String::from(""), None, None), create_value(18446744073709551614, 1).to_strings(&context));
1215        assert_eq!((String::from("0x,00000000,ffffffff,ffffffff"), String::from(""), None, None), create_value(18446744073709551615, 1).to_strings(&context));
1216        assert_eq!((String::from("0x,00000001,00000000,00000000"), String::from(""), None, None), create_value(18446744073709551616, 1).to_strings(&context));
1217        assert_eq!((String::from("0x,00000001,00000000,00000001"), String::from(""), None, None), create_value(18446744073709551617, 1).to_strings(&context));
1218        assert_eq!((String::from("0x,ffffffff,00000000,00000000"), String::from(""), None, None), create_value(-18446744073709551616, 1).to_strings(&context));
1219        assert_eq!((String::from("0x,ffffffff,00000000,00000001"), String::from(""), None, None), create_value(-18446744073709551615, 1).to_strings(&context));
1220        assert_eq!((String::from("0x,ffffffff,80000000,00000000"), String::from(""), None, None), create_value(-9223372036854775808, 1).to_strings(&context));
1221        assert_eq!((String::from("0x,ffffffff,80000000,00000001"), String::from(""), None, None), create_value(-9223372036854775807, 1).to_strings(&context));
1222        assert_eq!((String::from("0x,ffffffff,ffffffff,00000000"), String::from(""), None, None), create_value(-4294967296, 1).to_strings(&context));
1223        assert_eq!((String::from("0x,ffffffff,ffffffff,00000001"), String::from(""), None, None), create_value(-4294967295, 1).to_strings(&context));
1224        assert_eq!((String::from("0x,ffffffff,ffffffff,80000000"), String::from(""), None, None), create_value(-2147483648, 1).to_strings(&context));
1225        assert_eq!((String::from("0x,ffffffff,ffffffff,80000001"), String::from(""), None, None), create_value(-2147483647, 1).to_strings(&context));
1226        assert_eq!((String::from("0x,ffffffff,ffffffff,fffffffe"), String::from(""), None, None), create_value(-2, 1).to_strings(&context));
1227        assert_eq!((String::from("0x,ffffffff,ffffffff,ffffffff"), String::from(""), None, None), create_value(-1, 1).to_strings(&context));
1228    }
1229
1230    #[test]
1231    fn test_hexadecimal_is_measured_from_valid() {
1232        assert_eq!(1, create_value(0, 1).measure_hexadecimal()); // "00000000"
1233        assert_eq!(1, create_value(1, 1).measure_hexadecimal()); // "00000001"
1234        assert_eq!(1, create_value(2147483646, 1).measure_hexadecimal()); // "7ffffffe"
1235        assert_eq!(1, create_value(2147483647, 1).measure_hexadecimal()); // "7fffffff"
1236        assert_eq!(2, create_value(2147483648, 1).measure_hexadecimal()); // "00000000 80000000"
1237        assert_eq!(2, create_value(2147483649, 1).measure_hexadecimal()); // "00000000 80000001"
1238        assert_eq!(2, create_value(4294967294, 1).measure_hexadecimal()); // "00000000 fffffffe"
1239        assert_eq!(2, create_value(4294967295, 1).measure_hexadecimal()); // "00000000 ffffffff"
1240        assert_eq!(2, create_value(4294967296, 1).measure_hexadecimal()); // "00000001 00000000"
1241        assert_eq!(2, create_value(4294967297, 1).measure_hexadecimal()); // "00000001 00000001"
1242        assert_eq!(2, create_value(9223372036854775806, 1).measure_hexadecimal()); // "7fffffff fffffffe"
1243        assert_eq!(2, create_value(9223372036854775807, 1).measure_hexadecimal()); // "7fffffff ffffffff"
1244        assert_eq!(3, create_value(9223372036854775808, 1).measure_hexadecimal()); // "00000000 80000000 00000000"
1245        assert_eq!(3, create_value(9223372036854775809, 1).measure_hexadecimal()); // "00000000 80000000 00000001"
1246        assert_eq!(3, create_value(18446744073709551614, 1).measure_hexadecimal()); // "00000000 ffffffff fffffffe"
1247        assert_eq!(3, create_value(18446744073709551615, 1).measure_hexadecimal()); // "00000000 ffffffff ffffffff"
1248        assert_eq!(3, create_value(18446744073709551616, 1).measure_hexadecimal()); // "00000001 00000000 00000000"
1249        assert_eq!(3, create_value(18446744073709551617, 1).measure_hexadecimal()); // "00000001 00000000 00000001"
1250        assert_eq!(3, create_value(-18446744073709551616, 1).measure_hexadecimal()); // "ffffffff 00000000 00000000"
1251        assert_eq!(3, create_value(-18446744073709551615, 1).measure_hexadecimal()); // "ffffffff 00000000 00000001"
1252        assert_eq!(2, create_value(-9223372036854775808, 1).measure_hexadecimal()); // "80000000 00000000"
1253        assert_eq!(2, create_value(-9223372036854775807, 1).measure_hexadecimal()); // "80000000 00000001"
1254        assert_eq!(2, create_value(-4294967296, 1).measure_hexadecimal()); // "ffffffff 00000000"
1255        assert_eq!(2, create_value(-4294967295, 1).measure_hexadecimal()); // "ffffffff 00000001"
1256        assert_eq!(1, create_value(-2147483648, 1).measure_hexadecimal()); // "80000000"
1257        assert_eq!(1, create_value(-2147483647, 1).measure_hexadecimal()); // "80000001"
1258        assert_eq!(1, create_value(-2, 1).measure_hexadecimal()); // "fffffffe"
1259        assert_eq!(1, create_value(-1, 1).measure_hexadecimal()); // "ffffffff"
1260    }
1261
1262    #[test]
1263    fn test_time_is_formatted_without_separator() {
1264        let context = Context::new().with_sep(true).with_dp(Some(6));
1265        assert_time("2024-06-30T12:00:00", ".000Z", create_value(1719748800000, 1000), &context);
1266        assert_time("2024-06-30T12:00:00", ".987Z", create_value(1719748800987, 1000), &context);
1267        assert_time("2024-12-31T12:00:00", ".000Z", create_value(1735646400000, 1000), &context);
1268        assert_time("2024-12-31T12:00:00", ".987Z", create_value(1735646400987, 1000), &context);
1269    }
1270
1271    #[test]
1272    fn test_delta_is_formatted_without_separator() {
1273        let context = Context::new().with_sep(true).with_dp(Some(6));
1274        assert_delta("00", ".000", create_value(0, 1), &context);
1275        assert_delta("59", ".999", create_value(59999, 1000), &context);
1276        assert_delta("01:00", ".000", create_value(60000, 1000), &context);
1277        assert_delta("59:59", ".999", create_value(3599999, 1000), &context);
1278        assert_delta("01:00:00", ".000", create_value(3600000, 1000), &context);
1279        assert_delta("23:59:59", ".999", create_value(86399999, 1000), &context);
1280        assert_delta("1T00:00:00", ".000", create_value(86400000, 1000), &context);
1281        assert_delta("100T00:00:00", ".000", create_value(8640000000, 1000), &context);
1282        assert_delta("-59", ".999", create_value(-59999, 1000), &context);
1283        assert_delta("-01:00", ".000", create_value(-60000, 1000), &context);
1284        assert_delta("-59:59", ".999", create_value(-3599999, 1000), &context);
1285        assert_delta("-01:00:00", ".000", create_value(-3600000, 1000), &context);
1286        assert_delta("-23:59:59", ".999", create_value(-86399999, 1000), &context);
1287        assert_delta("-1T00:00:00", ".000", create_value(-86400000, 1000), &context);
1288        assert_delta("-100T00:00:00", ".000", create_value(-8640000000, 1000), &context);
1289    }
1290
1291    fn assert_time(integer: &str, fraction: &str, value: Value, context: &Context) {
1292        let expected = (String::from(integer), String::from(fraction), None, None);
1293        let actual = value.with_meaning(Meaning::Time).to_strings(context);
1294        assert_eq!(expected, actual);
1295    }
1296
1297    fn assert_delta(integer: &str, fraction: &str, value: Value, context: &Context) {
1298        let expected = (String::from(integer), String::from(fraction), None, None);
1299        let actual = value.with_meaning(Meaning::Delta).to_strings(context);
1300        assert_eq!(expected, actual);
1301    }
1302
1303    #[test]
1304    fn test_decimal_is_formatted_from_nan() {
1305        let expected = (String::from("NaN"), String::from(""), None, None);
1306        let context = Context::new();
1307        let actual = VALUE_NAN.to_strings(&context);
1308        assert_eq!(expected, actual);
1309    }
1310
1311    #[test]
1312    fn test_hexadecimal_is_measured_from_nan() {
1313        assert_eq!(1, VALUE_NAN.measure_hexadecimal());
1314    }
1315
1316    //       | Plain Delta Time
1317    // ------+------------------
1318    // Plain | Plain Delta Time
1319    // Delta | Delta Delta Time
1320    // Time  | Time  Time    -
1321
1322    #[test]
1323    fn test_plain_values_are_added_by_value() {
1324        assert_eq!(Value::calc_add(create_ref(55, 10), create_ref(25, 10)).ok(), Some(create_ref(8, 1)));
1325        assert_eq!(Value::calc_add(create_ref(55, 10), create_nan()).ok(), Some(create_nan()));
1326        assert_eq!(Value::calc_add(create_nan(), create_ref(25, 10)).ok(), Some(create_nan()));
1327        assert_eq!(Value::calc_add(create_nan(), create_nan()).ok(), Some(create_nan()));
1328    }
1329
1330    #[test]
1331    fn test_plain_values_are_added_by_meaning() {
1332        assert_eq!(perform_binary_ok(Value::calc_add, Meaning::Plain, Meaning::Plain), Some(Meaning::Plain));
1333        assert_eq!(perform_binary_ok(Value::calc_add, Meaning::Plain, Meaning::Delta), Some(Meaning::Delta));
1334        assert_eq!(perform_binary_ok(Value::calc_add, Meaning::Plain, Meaning::Time), Some(Meaning::Time));
1335        assert_eq!(perform_binary_ok(Value::calc_add, Meaning::Delta, Meaning::Plain), Some(Meaning::Delta));
1336        assert_eq!(perform_binary_ok(Value::calc_add, Meaning::Delta, Meaning::Delta), Some(Meaning::Delta));
1337        assert_eq!(perform_binary_ok(Value::calc_add, Meaning::Delta, Meaning::Time), Some(Meaning::Time));
1338        assert_eq!(perform_binary_ok(Value::calc_add, Meaning::Time, Meaning::Plain), Some(Meaning::Time));
1339        assert_eq!(perform_binary_ok(Value::calc_add, Meaning::Time, Meaning::Delta), Some(Meaning::Time));
1340        assert_eq!(perform_binary_err(Value::calc_add, Meaning::Time, Meaning::Time), Some(EngineError::BadTimeOp));
1341    }
1342
1343    //       | Plain Delta Time
1344    // ------+------------------
1345    // Plain | Plain Delta   -
1346    // Delta | Delta Delta   -
1347    // Time  | Time  Time  Delta
1348
1349    #[test]
1350    fn test_plain_values_are_subtracted_by_value() {
1351        assert_eq!(Value::calc_sub(create_ref(55, 10), create_ref(25, 10)).ok(), Some(create_ref(3, 1)));
1352        assert_eq!(Value::calc_sub(create_ref(55, 10), create_nan()).ok(), Some(create_nan()));
1353        assert_eq!(Value::calc_sub(create_nan(), create_ref(25, 10)).ok(), Some(create_nan()));
1354        assert_eq!(Value::calc_sub(create_nan(), create_nan()).ok(), Some(create_nan()));
1355    }
1356
1357    #[test]
1358    fn test_plain_values_are_subtracted_by_meaning() {
1359        assert_eq!(perform_binary_ok(Value::calc_sub, Meaning::Plain, Meaning::Plain), Some(Meaning::Plain));
1360        assert_eq!(perform_binary_ok(Value::calc_sub, Meaning::Plain, Meaning::Delta), Some(Meaning::Delta));
1361        assert_eq!(perform_binary_err(Value::calc_sub, Meaning::Plain, Meaning::Time), Some(EngineError::BadTimeOp));
1362        assert_eq!(perform_binary_ok(Value::calc_sub, Meaning::Delta, Meaning::Plain), Some(Meaning::Delta));
1363        assert_eq!(perform_binary_ok(Value::calc_sub, Meaning::Delta, Meaning::Delta), Some(Meaning::Delta));
1364        assert_eq!(perform_binary_err(Value::calc_sub, Meaning::Delta, Meaning::Time), Some(EngineError::BadTimeOp));
1365        assert_eq!(perform_binary_ok(Value::calc_sub, Meaning::Time, Meaning::Plain), Some(Meaning::Time));
1366        assert_eq!(perform_binary_ok(Value::calc_sub, Meaning::Time, Meaning::Delta), Some(Meaning::Time));
1367        assert_eq!(perform_binary_ok(Value::calc_sub, Meaning::Time, Meaning::Time), Some(Meaning::Delta));
1368    }
1369
1370    //       | Plain Delta Time
1371    // ------+------------------
1372    // Plain | Plain Delta   -
1373    // Delta | Delta   -     -
1374    // Time  |   -     -     -
1375
1376    #[test]
1377    fn test_plain_values_are_multiplied_by_value() {
1378        assert_eq!(Value::calc_mul(create_ref(55, 10), create_ref(25, 10)).ok(), Some(create_ref(1375, 100)));
1379        assert_eq!(Value::calc_mul(create_ref(55, 10), create_nan()).ok(), Some(create_nan()));
1380        assert_eq!(Value::calc_mul(create_nan(), create_ref(25, 10)).ok(), Some(create_nan()));
1381        assert_eq!(Value::calc_mul(create_nan(), create_nan()).ok(), Some(create_nan()));
1382    }
1383
1384    #[test]
1385    fn test_plain_values_are_multiplied_by_meaning() {
1386        assert_eq!(perform_binary_ok(Value::calc_mul, Meaning::Plain, Meaning::Plain), Some(Meaning::Plain));
1387        assert_eq!(perform_binary_ok(Value::calc_mul, Meaning::Plain, Meaning::Delta), Some(Meaning::Delta));
1388        assert_eq!(perform_binary_err(Value::calc_mul, Meaning::Plain, Meaning::Time), Some(EngineError::BadTimeOp));
1389        assert_eq!(perform_binary_ok(Value::calc_mul, Meaning::Delta, Meaning::Plain), Some(Meaning::Delta));
1390        assert_eq!(perform_binary_err(Value::calc_mul, Meaning::Delta, Meaning::Delta), Some(EngineError::BadTimeOp));
1391        assert_eq!(perform_binary_err(Value::calc_mul, Meaning::Delta, Meaning::Time), Some(EngineError::BadTimeOp));
1392        assert_eq!(perform_binary_err(Value::calc_mul, Meaning::Time, Meaning::Plain), Some(EngineError::BadTimeOp));
1393        assert_eq!(perform_binary_err(Value::calc_mul, Meaning::Time, Meaning::Delta), Some(EngineError::BadTimeOp));
1394        assert_eq!(perform_binary_err(Value::calc_mul, Meaning::Time, Meaning::Time), Some(EngineError::BadTimeOp));
1395    }
1396
1397    //       | Plain Delta Time
1398    // ------+------------------
1399    // Plain | Plain   -     -
1400    // Delta | Delta   -     -
1401    // Time  |   -     -     -
1402
1403    #[test]
1404    fn test_plain_values_are_divided_by_value() {
1405        assert_eq!(Value::calc_div(create_ref(55, 10), create_ref(25, 10)).ok(), Some(create_ref(22, 10)));
1406        assert_eq!(Value::calc_div(create_ref(55, 10), create_nan()).ok(), Some(create_nan()));
1407        assert_eq!(Value::calc_div(create_nan(), create_ref(25, 10)).ok(), Some(create_nan()));
1408        assert_eq!(Value::calc_div(create_nan(), create_nan()).ok(), Some(create_nan()));
1409    }
1410
1411    #[test]
1412    fn test_plain_values_are_divided_by_zero() {
1413        assert_eq!(Value::calc_div(create_ref(55, 10), create_ref(0, 1)).ok(), Some(create_nan()));
1414        assert_eq!(Value::calc_div(create_nan(), create_ref(0, 1)).ok(), Some(create_nan()));
1415    }
1416
1417    #[test]
1418    fn test_plain_values_are_divided_by_meaning() {
1419        assert_eq!(perform_binary_ok(Value::calc_div, Meaning::Plain, Meaning::Plain), Some(Meaning::Plain));
1420        assert_eq!(perform_binary_err(Value::calc_div, Meaning::Plain, Meaning::Delta), Some(EngineError::BadTimeOp));
1421        assert_eq!(perform_binary_err(Value::calc_div, Meaning::Plain, Meaning::Time), Some(EngineError::BadTimeOp));
1422        assert_eq!(perform_binary_ok(Value::calc_div, Meaning::Delta, Meaning::Plain), Some(Meaning::Delta));
1423        assert_eq!(perform_binary_err(Value::calc_div, Meaning::Delta, Meaning::Delta), Some(EngineError::BadTimeOp));
1424        assert_eq!(perform_binary_err(Value::calc_div, Meaning::Delta, Meaning::Time), Some(EngineError::BadTimeOp));
1425        assert_eq!(perform_binary_err(Value::calc_div, Meaning::Time, Meaning::Plain), Some(EngineError::BadTimeOp));
1426        assert_eq!(perform_binary_err(Value::calc_div, Meaning::Time, Meaning::Delta), Some(EngineError::BadTimeOp));
1427        assert_eq!(perform_binary_err(Value::calc_div, Meaning::Time, Meaning::Time), Some(EngineError::BadTimeOp));
1428    }
1429
1430    #[test]
1431    fn test_plain_values_are_remaindered_by_value() {
1432        assert_eq!(Value::calc_mod(create_ref(55, 10), create_ref(25, 10)).ok(), Some(create_ref(5, 10)));
1433        assert_eq!(Value::calc_mod(create_ref(55, 10), create_ref(-25, 10)).ok(), Some(create_ref(5, 10)));
1434        assert_eq!(Value::calc_mod(create_ref(-55, 10), create_ref(25, 10)).ok(), Some(create_ref(-5, 10)));
1435        assert_eq!(Value::calc_mod(create_ref(-55, 10), create_ref(-25, 10)).ok(), Some(create_ref(-5, 10)));
1436        assert_eq!(Value::calc_mod(create_ref(55, 10), create_nan()).ok(), Some(create_nan()));
1437        assert_eq!(Value::calc_mod(create_ref(-55, 10), create_nan()).ok(), Some(create_nan()));
1438        assert_eq!(Value::calc_mod(create_nan(), create_ref(25, 10)).ok(), Some(create_nan()));
1439        assert_eq!(Value::calc_mod(create_nan(), create_ref(-25, 10)).ok(), Some(create_nan()));
1440        assert_eq!(Value::calc_mod(create_nan(), create_nan()).ok(), Some(create_nan()));
1441    }
1442
1443    #[test]
1444    fn test_plain_values_are_remaindered_by_zero() {
1445        assert_eq!(Value::calc_mod(create_ref(55, 10), create_ref(0, 1)).ok(), Some(create_nan()));
1446        assert_eq!(Value::calc_mod(create_nan(), create_ref(0, 1)).ok(), Some(create_nan()));
1447    }
1448
1449    #[test]
1450    fn test_plain_values_are_remaindered_by_meaning() {
1451        assert_eq!(perform_binary_ok(Value::calc_mod, Meaning::Plain, Meaning::Plain), Some(Meaning::Plain));
1452        assert_eq!(perform_binary_err(Value::calc_mod, Meaning::Plain, Meaning::Delta), Some(EngineError::BadTimeOp));
1453        assert_eq!(perform_binary_err(Value::calc_mod, Meaning::Plain, Meaning::Time), Some(EngineError::BadTimeOp));
1454        assert_eq!(perform_binary_ok(Value::calc_mod, Meaning::Delta, Meaning::Plain), Some(Meaning::Delta));
1455        assert_eq!(perform_binary_err(Value::calc_mod, Meaning::Delta, Meaning::Delta), Some(EngineError::BadTimeOp));
1456        assert_eq!(perform_binary_err(Value::calc_mod, Meaning::Delta, Meaning::Time), Some(EngineError::BadTimeOp));
1457        assert_eq!(perform_binary_err(Value::calc_mod, Meaning::Time, Meaning::Plain), Some(EngineError::BadTimeOp));
1458        assert_eq!(perform_binary_err(Value::calc_mod, Meaning::Time, Meaning::Delta), Some(EngineError::BadTimeOp));
1459        assert_eq!(perform_binary_err(Value::calc_mod, Meaning::Time, Meaning::Time), Some(EngineError::BadTimeOp));
1460    }
1461
1462    // Plain | Plain
1463    // Delta | Delta
1464    // Time  |   -
1465
1466    #[test]
1467    fn test_plain_values_are_negated_by_value() {
1468        assert_eq!(Value::calc_neg(create_ref(5, 10)).ok(), Some(create_ref(-5, 10)));
1469        assert_eq!(Value::calc_neg(create_ref(-5, 10)).ok(), Some(create_ref(5, 10)));
1470        assert_eq!(Value::calc_neg(create_nan()).ok(), Some(create_nan()));
1471    }
1472
1473    #[test]
1474    fn test_plain_values_are_negated_by_meaning() {
1475        assert_eq!(perform_unary_ok(Value::calc_neg, Meaning::Plain), Some(Meaning::Plain));
1476        assert_eq!(perform_unary_ok(Value::calc_neg, Meaning::Delta), Some(Meaning::Delta));
1477        assert_eq!(perform_unary_err(Value::calc_neg, Meaning::Time), Some(EngineError::BadTimeOp));
1478    }
1479
1480    // Plain | Plain
1481    // Delta |   -
1482    // Time  |   -
1483
1484    #[test]
1485    fn test_plain_values_are_inverted_if_valid() {
1486        assert_eq!(Value::calc_inv(create_ref(5, 10)).ok(), Some(create_ref(10, 5)));
1487        assert_eq!(Value::calc_inv(create_ref(-5, 10)).ok(), Some(create_ref(-10, 5)));
1488        assert_eq!(Value::calc_inv(create_nan()).ok(), Some(create_nan()));
1489    }
1490
1491    #[test]
1492    fn test_plain_values_are_inverted_if_zero() {
1493        assert_eq!(Value::calc_inv(create_ref(0, 1)).ok(), Some(create_nan()));
1494    }
1495
1496    #[test]
1497    fn test_plain_values_are_inverted_by_meaning() {
1498        assert_eq!(perform_unary_ok(Value::calc_inv, Meaning::Plain), Some(Meaning::Plain));
1499        assert_eq!(perform_unary_err(Value::calc_inv, Meaning::Delta), Some(EngineError::BadTimeOp));
1500        assert_eq!(perform_unary_err(Value::calc_inv, Meaning::Time), Some(EngineError::BadTimeOp));
1501    }
1502
1503    //       | Plain Delta Time
1504    // ------+------------------
1505    // Plain | Plain   -     -
1506    // Delta |   -     -     -
1507    // Time  |   -     -     -
1508
1509    #[test]
1510    fn test_plain_values_are_raised_to_integer_power() {
1511        assert_eq!(Value::calc_pow(create_ref(3, 1), create_ref(4, 1)).ok(), Some(create_ref(81, 1)));
1512        assert_eq!(Value::calc_pow(create_ref(3, 1), create_nan()).ok(), Some(create_nan()));
1513        assert_eq!(Value::calc_pow(create_nan(), create_ref(4, 1)).ok(), Some(create_nan()));
1514        assert_eq!(Value::calc_pow(create_nan(), create_nan()).ok(), Some(create_nan()));
1515    }
1516
1517    #[test]
1518    fn test_plain_values_are_raised_to_fractional_power() {
1519        assert_eq!(Value::calc_pow(create_ref(3, 1), create_nan()).ok(), Some(create_nan()));
1520        assert_eq!(Value::calc_pow(create_nan(), create_ref(1, 2)).ok(), Some(create_nan()));
1521        assert_eq!(Value::calc_pow(create_nan(), create_nan()).ok(), Some(create_nan()));
1522    }
1523
1524    #[test]
1525    fn test_plain_values_are_raised_by_meaning() {
1526        assert_eq!(perform_binary_ok(Value::calc_pow, Meaning::Plain, Meaning::Plain), Some(Meaning::Plain));
1527        assert_eq!(perform_binary_err(Value::calc_pow, Meaning::Plain, Meaning::Delta), Some(EngineError::BadTimeOp));
1528        assert_eq!(perform_binary_err(Value::calc_pow, Meaning::Plain, Meaning::Time), Some(EngineError::BadTimeOp));
1529        assert_eq!(perform_binary_err(Value::calc_pow, Meaning::Delta, Meaning::Plain), Some(EngineError::BadTimeOp));
1530        assert_eq!(perform_binary_err(Value::calc_pow, Meaning::Delta, Meaning::Delta), Some(EngineError::BadTimeOp));
1531        assert_eq!(perform_binary_err(Value::calc_pow, Meaning::Delta, Meaning::Time), Some(EngineError::BadTimeOp));
1532        assert_eq!(perform_binary_err(Value::calc_pow, Meaning::Time, Meaning::Plain), Some(EngineError::BadTimeOp));
1533        assert_eq!(perform_binary_err(Value::calc_pow, Meaning::Time, Meaning::Delta), Some(EngineError::BadTimeOp));
1534        assert_eq!(perform_binary_err(Value::calc_pow, Meaning::Time, Meaning::Time), Some(EngineError::BadTimeOp));
1535    }
1536
1537    // Plain | Plain
1538    // Delta |   -
1539    // Time  |   -
1540
1541    #[test]
1542    fn test_plain_values_have_square_root_if_positive() {
1543        assert_eq!(Value::calc_sqrt(create_nan()).ok(), Some(create_nan()));
1544    }
1545
1546    #[test]
1547    fn test_plain_values_have_square_root_if_negative() {
1548        assert_eq!(Value::calc_sqrt(create_ref(-3, 1)).ok(), Some(create_nan()));
1549    }
1550
1551    #[test]
1552    fn test_plain_values_have_square_root_by_meaning() {
1553        assert_eq!(perform_unary_ok(Value::calc_sqrt, Meaning::Plain), Some(Meaning::Plain));
1554        assert_eq!(perform_unary_err(Value::calc_sqrt, Meaning::Delta), Some(EngineError::BadTimeOp));
1555        assert_eq!(perform_unary_err(Value::calc_sqrt, Meaning::Time), Some(EngineError::BadTimeOp));
1556    }
1557
1558    #[test]
1559    fn test_plain_values_are_summed() {
1560        assert_eq!(Some(create_ref(0, 1)), Value::calc_sum(vec![]).ok());
1561        assert_eq!(Some(create_ref(0, 1)), Value::calc_sum(vec![create_nan(), create_nan(), create_nan()]).ok());
1562        assert_eq!(Some(create_ref(25, 10)), Value::calc_sum(vec![create_ref(25, 10), create_nan(), create_nan()]).ok());
1563        assert_eq!(Some(create_ref(65, 10)), Value::calc_sum(vec![create_ref(25, 10), create_ref(4, 1), create_nan()]).ok());
1564        assert_eq!(Some(create_ref(120, 10)), Value::calc_sum(vec![create_ref(25, 10), create_ref(4, 1), create_ref(55, 10)]).ok());
1565    }
1566
1567    #[test]
1568    fn test_plain_values_are_producted() {
1569        assert_eq!(Some(create_ref(1, 1)), Value::calc_prod(vec![]).ok());
1570        assert_eq!(Some(create_ref(1, 1)), Value::calc_prod(vec![create_nan(), create_nan(), create_nan()]).ok());
1571        assert_eq!(Some(create_ref(25, 10)), Value::calc_prod(vec![create_ref(25, 10), create_nan(), create_nan()]).ok());
1572        assert_eq!(Some(create_ref(100, 10)), Value::calc_prod(vec![create_ref(25, 10), create_ref(4, 1), create_nan()]).ok());
1573        assert_eq!(Some(create_ref(550, 10)), Value::calc_prod(vec![create_ref(25, 10), create_ref(4, 1), create_ref(55, 10)]).ok());
1574    }
1575
1576    #[test]
1577    fn test_integer_sequences_are_generated_no_step() {
1578        let expected_inc = vec![
1579            create_ref(95, 10),
1580            create_ref(105, 10),
1581            create_ref(115, 10),
1582        ];
1583        let expected_same = vec![
1584            create_ref(105, 10),
1585        ];
1586        let expected_dec = vec![
1587            create_ref(115, 10),
1588            create_ref(105, 10),
1589            create_ref(95, 10),
1590        ];
1591        assert_eq!(Some(expected_inc), Value::calc_seq(create_ref(95, 10), create_ref(115, 10)).ok());
1592        assert_eq!(Some(expected_same), Value::calc_seq(create_ref(105, 10), create_ref(105, 10)).ok());
1593        assert_eq!(Some(expected_dec), Value::calc_seq(create_ref(115, 10), create_ref(95, 10)).ok());
1594    }
1595
1596    #[test]
1597    fn test_integer_sequences_are_generated_with_step() {
1598        let expected_inc = vec![
1599            create_ref(0, 10),
1600            create_ref(5, 10),
1601            create_ref(10, 10),
1602        ];
1603        let expected_same = vec![
1604            create_ref(5, 10),
1605        ];
1606        let expected_dec = vec![
1607            create_ref(10, 10),
1608            create_ref(5, 10),
1609            create_ref(0, 10),
1610        ];
1611        assert_eq!(Some(expected_inc.clone()), Value::calc_step(create_ref(0, 10), create_ref(5, 10), create_ref(10, 10)).ok());
1612        assert_eq!(Some(expected_inc.clone()), Value::calc_step(create_ref(0, 10), create_ref(5, 10), create_ref(12, 10)).ok());
1613        assert_eq!(Some(expected_inc.clone()), Value::calc_step(create_ref(0, 10), create_ref(-5, 10), create_ref(10, 10)).ok());
1614        assert_eq!(Some(expected_inc.clone()), Value::calc_step(create_ref(0, 10), create_ref(-5, 10), create_ref(12, 10)).ok());
1615        assert_eq!(Some(expected_same.clone()), Value::calc_step(create_ref(5, 10), create_ref(0, 10), create_ref(10, 10)).ok());
1616        assert_eq!(Some(expected_same.clone()), Value::calc_step(create_ref(5, 10), create_ref(0, 10), create_ref(5, 10)).ok());
1617        assert_eq!(Some(expected_same.clone()), Value::calc_step(create_ref(5, 10), create_ref(0, 10), create_ref(0, 10)).ok());
1618        assert_eq!(Some(expected_dec.clone()), Value::calc_step(create_ref(10, 10), create_ref(5, 10), create_ref(0, 10)).ok());
1619        assert_eq!(Some(expected_dec.clone()), Value::calc_step(create_ref(10, 10), create_ref(5, 10), create_ref(-2, 10)).ok());
1620        assert_eq!(Some(expected_dec.clone()), Value::calc_step(create_ref(10, 10), create_ref(-5, 10), create_ref(0, 10)).ok());
1621        assert_eq!(Some(expected_dec.clone()), Value::calc_step(create_ref(10, 10), create_ref(-5, 10), create_ref(-2, 10)).ok());
1622    }
1623
1624    #[test]
1625    fn test_stack_is_sorted() {
1626        let expected = vec![
1627            create_nan(),
1628            create_ref(-15, 10),
1629            create_ref(-10, 10),
1630            create_ref(-5, 10),
1631            create_ref(0, 10),
1632            create_ref(5, 10),
1633            create_ref(10, 10),
1634            create_ref(15, 10),
1635        ];
1636        let original = vec![
1637            create_ref(0, 10),
1638            create_ref(5, 10),
1639            create_ref(-5, 10),
1640            create_ref(10, 10),
1641            create_ref(-10, 10),
1642            create_ref(15, 10),
1643            create_ref(-15, 10),
1644            create_nan(),
1645        ];
1646        assert_eq!(Some(expected), Value::sort_seq(original).ok());
1647    }
1648
1649    #[test]
1650    fn test_stack_is_reversed() {
1651        let expected = vec![
1652            create_nan(),
1653            create_ref(-15, 10),
1654            create_ref(15, 10),
1655            create_ref(-10, 10),
1656            create_ref(10, 10),
1657            create_ref(-5, 10),
1658            create_ref(5, 10),
1659            create_ref(0, 10),
1660        ];
1661        let original = vec![
1662            create_ref(0, 10),
1663            create_ref(5, 10),
1664            create_ref(-5, 10),
1665            create_ref(10, 10),
1666            create_ref(-10, 10),
1667            create_ref(15, 10),
1668            create_ref(-15, 10),
1669            create_nan(),
1670        ];
1671        assert_eq!(Some(expected), Value::rev_seq(original).ok());
1672    }
1673
1674    //       | Plain Delta Time
1675    // ------+------------------
1676    // Plain | Plain   -     -
1677    // Delta |   -     -     -
1678    // Time  |   -     -     -
1679
1680    #[test]
1681    fn test_plain_values_have_bitwise_and_by_value() {
1682        assert_eq!(Value::calc_and(create_ref(0xff00, 1), create_ref(0xf0f0, 1)).ok(), Some(create_ref(0xf000, 1)));
1683        assert_eq!(Value::calc_and(create_ref(0xff00, 1), create_nan()).ok(), Some(create_nan()));
1684        assert_eq!(Value::calc_and(create_nan(), create_ref(0xf0f0, 1)).ok(), Some(create_nan()));
1685        assert_eq!(Value::calc_and(create_nan(), create_nan()).ok(), Some(create_nan()));
1686    }
1687
1688    #[test]
1689    fn test_plain_values_have_bitwise_and_by_meaning() {
1690        assert_eq!(perform_binary_ok(Value::calc_and, Meaning::Plain, Meaning::Plain), Some(Meaning::Plain));
1691        assert_eq!(perform_binary_err(Value::calc_and, Meaning::Plain, Meaning::Delta), Some(EngineError::BadTimeOp));
1692        assert_eq!(perform_binary_err(Value::calc_and, Meaning::Plain, Meaning::Time), Some(EngineError::BadTimeOp));
1693        assert_eq!(perform_binary_err(Value::calc_and, Meaning::Delta, Meaning::Plain), Some(EngineError::BadTimeOp));
1694        assert_eq!(perform_binary_err(Value::calc_and, Meaning::Delta, Meaning::Delta), Some(EngineError::BadTimeOp));
1695        assert_eq!(perform_binary_err(Value::calc_and, Meaning::Delta, Meaning::Time), Some(EngineError::BadTimeOp));
1696        assert_eq!(perform_binary_err(Value::calc_and, Meaning::Time, Meaning::Plain), Some(EngineError::BadTimeOp));
1697        assert_eq!(perform_binary_err(Value::calc_and, Meaning::Time, Meaning::Delta), Some(EngineError::BadTimeOp));
1698        assert_eq!(perform_binary_err(Value::calc_and, Meaning::Time, Meaning::Time), Some(EngineError::BadTimeOp));
1699    }
1700
1701    #[test]
1702    fn test_plain_values_have_bitwise_or_by_value() {
1703        assert_eq!(Value::calc_or(create_ref(0xff00, 1), create_ref(0xf0f0, 1)).ok(), Some(create_ref(0xfff0, 1)));
1704        assert_eq!(Value::calc_or(create_ref(0xff00, 1), create_nan()).ok(), Some(create_nan()));
1705        assert_eq!(Value::calc_or(create_nan(), create_ref(0xf0f0, 1)).ok(), Some(create_nan()));
1706        assert_eq!(Value::calc_or(create_nan(), create_nan()).ok(), Some(create_nan()));
1707    }
1708
1709    #[test]
1710    fn test_plain_values_have_bitwise_or_by_meaning() {
1711        assert_eq!(perform_binary_ok(Value::calc_or, Meaning::Plain, Meaning::Plain), Some(Meaning::Plain));
1712        assert_eq!(perform_binary_err(Value::calc_or, Meaning::Plain, Meaning::Delta), Some(EngineError::BadTimeOp));
1713        assert_eq!(perform_binary_err(Value::calc_or, Meaning::Plain, Meaning::Time), Some(EngineError::BadTimeOp));
1714        assert_eq!(perform_binary_err(Value::calc_or, Meaning::Delta, Meaning::Plain), Some(EngineError::BadTimeOp));
1715        assert_eq!(perform_binary_err(Value::calc_or, Meaning::Delta, Meaning::Delta), Some(EngineError::BadTimeOp));
1716        assert_eq!(perform_binary_err(Value::calc_or, Meaning::Delta, Meaning::Time), Some(EngineError::BadTimeOp));
1717        assert_eq!(perform_binary_err(Value::calc_or, Meaning::Time, Meaning::Plain), Some(EngineError::BadTimeOp));
1718        assert_eq!(perform_binary_err(Value::calc_or, Meaning::Time, Meaning::Delta), Some(EngineError::BadTimeOp));
1719        assert_eq!(perform_binary_err(Value::calc_or, Meaning::Time, Meaning::Time), Some(EngineError::BadTimeOp));
1720    }
1721
1722    #[test]
1723    fn test_plain_values_have_bitwise_xor_by_value() {
1724        assert_eq!(Value::calc_xor(create_ref(0xff00, 1), create_ref(0xf0f0, 1)).ok(), Some(create_ref(0x0ff0, 1)));
1725        assert_eq!(Value::calc_xor(create_ref(0xff00, 1), create_nan()).ok(), Some(create_nan()));
1726        assert_eq!(Value::calc_xor(create_nan(), create_ref(0xf0f0, 1)).ok(), Some(create_nan()));
1727        assert_eq!(Value::calc_xor(create_nan(), create_nan()).ok(), Some(create_nan()));
1728    }
1729
1730    #[test]
1731    fn test_plain_values_have_bitwise_xor_by_meaning() {
1732        assert_eq!(perform_binary_ok(Value::calc_xor, Meaning::Plain, Meaning::Plain), Some(Meaning::Plain));
1733        assert_eq!(perform_binary_err(Value::calc_xor, Meaning::Plain, Meaning::Delta), Some(EngineError::BadTimeOp));
1734        assert_eq!(perform_binary_err(Value::calc_xor, Meaning::Plain, Meaning::Time), Some(EngineError::BadTimeOp));
1735        assert_eq!(perform_binary_err(Value::calc_xor, Meaning::Delta, Meaning::Plain), Some(EngineError::BadTimeOp));
1736        assert_eq!(perform_binary_err(Value::calc_xor, Meaning::Delta, Meaning::Delta), Some(EngineError::BadTimeOp));
1737        assert_eq!(perform_binary_err(Value::calc_xor, Meaning::Delta, Meaning::Time), Some(EngineError::BadTimeOp));
1738        assert_eq!(perform_binary_err(Value::calc_xor, Meaning::Time, Meaning::Plain), Some(EngineError::BadTimeOp));
1739        assert_eq!(perform_binary_err(Value::calc_xor, Meaning::Time, Meaning::Delta), Some(EngineError::BadTimeOp));
1740        assert_eq!(perform_binary_err(Value::calc_xor, Meaning::Time, Meaning::Time), Some(EngineError::BadTimeOp));
1741    }
1742
1743    #[test]
1744    fn test_plain_values_are_shifted_left_by_value() {
1745        assert_eq!(Value::calc_shl(create_ref(35, 10), create_ref(29, 10)).ok(), Some(create_ref(14, 1)));
1746        assert_eq!(Value::calc_shl(create_ref(-35, 10), create_ref(29, 10)).ok(), Some(create_ref(-14, 1)));
1747        assert_eq!(Value::calc_shl(create_ref(35, 10), create_ref(-29, 10)).ok(), Some(create_ref(875, 1000)));
1748        assert_eq!(Value::calc_shl(create_ref(-35, 10), create_ref(-29, 10)).ok(), Some(create_ref(-875, 1000)));
1749        assert_eq!(Value::calc_shl(create_ref(35, 10), create_nan()).ok(), Some(create_nan()));
1750        assert_eq!(Value::calc_shl(create_ref(-35, 10), create_nan()).ok(), Some(create_nan()));
1751        assert_eq!(Value::calc_shl(create_nan(), create_ref(29, 10)).ok(), Some(create_nan()));
1752        assert_eq!(Value::calc_shl(create_nan(), create_ref(-29, 10)).ok(), Some(create_nan()));
1753        assert_eq!(Value::calc_shl(create_nan(), create_nan()).ok(), Some(create_nan()));
1754    }
1755
1756    #[test]
1757    fn test_plain_values_are_shifted_left_by_meaning() {
1758        assert_eq!(perform_binary_ok(Value::calc_shl, Meaning::Plain, Meaning::Plain), Some(Meaning::Plain));
1759        assert_eq!(perform_binary_err(Value::calc_shl, Meaning::Plain, Meaning::Delta), Some(EngineError::BadTimeOp));
1760        assert_eq!(perform_binary_err(Value::calc_shl, Meaning::Plain, Meaning::Time), Some(EngineError::BadTimeOp));
1761        assert_eq!(perform_binary_err(Value::calc_shl, Meaning::Delta, Meaning::Plain), Some(EngineError::BadTimeOp));
1762        assert_eq!(perform_binary_err(Value::calc_shl, Meaning::Delta, Meaning::Delta), Some(EngineError::BadTimeOp));
1763        assert_eq!(perform_binary_err(Value::calc_shl, Meaning::Delta, Meaning::Time), Some(EngineError::BadTimeOp));
1764        assert_eq!(perform_binary_err(Value::calc_shl, Meaning::Time, Meaning::Plain), Some(EngineError::BadTimeOp));
1765        assert_eq!(perform_binary_err(Value::calc_shl, Meaning::Time, Meaning::Delta), Some(EngineError::BadTimeOp));
1766        assert_eq!(perform_binary_err(Value::calc_shl, Meaning::Time, Meaning::Time), Some(EngineError::BadTimeOp));
1767    }
1768
1769    #[test]
1770    fn test_plain_values_are_shifted_right_by_value() {
1771        assert_eq!(Value::calc_shr(create_ref(35, 10), create_ref(29, 10)).ok(), Some(create_ref(875, 1000)));
1772        assert_eq!(Value::calc_shr(create_ref(-35, 10), create_ref(29, 10)).ok(), Some(create_ref(-875, 1000)));
1773        assert_eq!(Value::calc_shr(create_ref(35, 10), create_ref(-29, 10)).ok(), Some(create_ref(14, 1)));
1774        assert_eq!(Value::calc_shr(create_ref(-35, 10), create_ref(-29, 10)).ok(), Some(create_ref(-14, 1)));
1775        assert_eq!(Value::calc_shr(create_ref(35, 10), create_nan()).ok(), Some(create_nan()));
1776        assert_eq!(Value::calc_shr(create_ref(-35, 10), create_nan()).ok(), Some(create_nan()));
1777        assert_eq!(Value::calc_shr(create_nan(), create_ref(29, 10)).ok(), Some(create_nan()));
1778        assert_eq!(Value::calc_shr(create_nan(), create_ref(-29, 10)).ok(), Some(create_nan()));
1779        assert_eq!(Value::calc_shr(create_nan(), create_nan()).ok(), Some(create_nan()));
1780    }
1781
1782    #[test]
1783    fn test_plain_values_are_shifted_right_by_meaning() {
1784        assert_eq!(perform_binary_ok(Value::calc_shr, Meaning::Plain, Meaning::Plain), Some(Meaning::Plain));
1785        assert_eq!(perform_binary_err(Value::calc_shr, Meaning::Plain, Meaning::Delta), Some(EngineError::BadTimeOp));
1786        assert_eq!(perform_binary_err(Value::calc_shr, Meaning::Plain, Meaning::Time), Some(EngineError::BadTimeOp));
1787        assert_eq!(perform_binary_err(Value::calc_shr, Meaning::Delta, Meaning::Plain), Some(EngineError::BadTimeOp));
1788        assert_eq!(perform_binary_err(Value::calc_shr, Meaning::Delta, Meaning::Delta), Some(EngineError::BadTimeOp));
1789        assert_eq!(perform_binary_err(Value::calc_shr, Meaning::Delta, Meaning::Time), Some(EngineError::BadTimeOp));
1790        assert_eq!(perform_binary_err(Value::calc_shr, Meaning::Time, Meaning::Plain), Some(EngineError::BadTimeOp));
1791        assert_eq!(perform_binary_err(Value::calc_shr, Meaning::Time, Meaning::Delta), Some(EngineError::BadTimeOp));
1792        assert_eq!(perform_binary_err(Value::calc_shr, Meaning::Time, Meaning::Time), Some(EngineError::BadTimeOp));
1793    }
1794
1795    fn perform_unary_ok(
1796        function: fn(ValueRef) -> MyResult<ValueRef>,
1797        meaning: Meaning,
1798    ) -> Option<Meaning> {
1799        let value = create_value(1, 1).with_meaning(meaning);
1800        let value = Rc::new(RefCell::new(value));
1801        let result = function(value);
1802        result.ok().map(get_meaning)
1803    }
1804
1805    fn perform_unary_err(
1806        function: fn(ValueRef) -> MyResult<ValueRef>,
1807        meaning: Meaning,
1808    ) -> Option<EngineError> {
1809        let value = create_value(1, 1).with_meaning(meaning);
1810        let value = Rc::new(RefCell::new(value));
1811        let result = function(value);
1812        result.err().and_then(filter_error)
1813    }
1814
1815    fn perform_binary_ok(
1816        function: fn(ValueRef, ValueRef) -> MyResult<ValueRef>,
1817        lhs: Meaning,
1818        rhs: Meaning,
1819    ) -> Option<Meaning> {
1820        let lhs = create_value(1, 1).with_meaning(lhs);
1821        let rhs = create_value(1, 1).with_meaning(rhs);
1822        let lhs = Rc::new(RefCell::new(lhs));
1823        let rhs = Rc::new(RefCell::new(rhs));
1824        let result = function(lhs, rhs);
1825        result.ok().map(get_meaning)
1826    }
1827
1828    fn perform_binary_err(
1829        function: fn(ValueRef, ValueRef) -> MyResult<ValueRef>,
1830        lhs: Meaning,
1831        rhs: Meaning,
1832    ) -> Option<EngineError> {
1833        let lhs = create_value(1, 1).with_meaning(lhs);
1834        let rhs = create_value(1, 1).with_meaning(rhs);
1835        let lhs = Rc::new(RefCell::new(lhs));
1836        let rhs = Rc::new(RefCell::new(rhs));
1837        let result = function(lhs, rhs);
1838        result.err().and_then(filter_error)
1839    }
1840
1841    fn get_meaning(value: ValueRef) -> Meaning {
1842        value.borrow().meaning
1843    }
1844
1845    fn filter_error(error: MyError) -> Option<EngineError> {
1846        match error {
1847            MyError::Engine(error) => Some(error),
1848            _ => None,
1849        }
1850    }
1851
1852    fn create_value(numer: i128, denom: i128) -> Value {
1853        let number = create_ratio(numer, denom);
1854        Value::new(Some(number))
1855    }
1856
1857    fn create_ref(numer: i128, denom: i128) -> ValueRef {
1858        let number = create_ratio(numer, denom);
1859        let value = Value::new(Some(number));
1860        Rc::new(RefCell::new(value))
1861    }
1862
1863    pub fn create_nan() -> ValueRef {
1864        let value = Value::new(None);
1865        Rc::new(RefCell::new(value))
1866    }
1867
1868    pub fn parse_value(number: &str) -> ValueRef {
1869        let regex = regex!(r#"^(\S+)(?: \[(delta|time)\])?(?: = (\w+))?(?: # (.+))?$"#);
1870        let captures = regex.captures(number).unwrap();
1871        let number = captures.get(1).as_ref().map(Match::as_str).unwrap();
1872        let mut value = Value::from_string(number).unwrap();
1873        match captures.get(2).as_ref().map(Match::as_str) {
1874            Some("delta") => value.set_meaning(Meaning::Delta),
1875            Some("time") => value.set_meaning(Meaning::Time),
1876            _ => value.set_meaning(Meaning::Plain),
1877        }
1878        if let Some(variable) = captures.get(3).as_ref().map(Match::as_str) {
1879            value.set_variable(variable);
1880        }
1881        if let Some(comment) = captures.get(4).as_ref().map(Match::as_str) {
1882            value.set_comment(comment);
1883        }
1884        Rc::new(RefCell::new(value))
1885    }
1886
1887    pub fn parse_values(numbers: Vec<&str>) -> Vec<ValueRef> {
1888        numbers.iter().map(|x| parse_value(x)).collect()
1889    }
1890
1891    fn create_ratio(numer: i128, denom: i128) -> BigRational {
1892        let numer = BigInt::from(numer);
1893        let denom = BigInt::from(denom);
1894        BigRational::new(numer, denom)
1895    }
1896
1897    fn fudge_ratio(number: BigRational) -> Option<BigRational> {
1898        number.to_f64()
1899            .map(f64::sqrt)
1900            .and_then(BigRational::from_f64)
1901            .and_then(square_ratio)
1902    }
1903
1904    fn square_ratio(number: BigRational) -> Option<BigRational> {
1905        number.checked_mul(&number)
1906    }
1907
1908    fn opposite_ratio(number: BigRational) -> Option<BigRational> {
1909        create_ratio(2, 1).checked_mul(&number.round()).and_then(|x| x.checked_sub(&number))
1910    }
1911}