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
34impl 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 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" };
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 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 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 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 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 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 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 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 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 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 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#[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); let number2 = fudge_ratio(create_ratio(16, 8)).and_then(opposite_ratio); let number3 = fudge_ratio(create_ratio(16, 8)); let number4 = fudge_ratio(create_ratio(17, 8)); 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)); let number2 = fudge_ratio(create_ratio(1088924, 99000)); let number3 = fudge_ratio(create_ratio(1997457, 999000)); let number4 = fudge_ratio(create_ratio(19995891, 9999000)); 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()); assert_eq!(1, create_value(1, 1).measure_hexadecimal()); assert_eq!(1, create_value(2147483646, 1).measure_hexadecimal()); assert_eq!(1, create_value(2147483647, 1).measure_hexadecimal()); assert_eq!(2, create_value(2147483648, 1).measure_hexadecimal()); assert_eq!(2, create_value(2147483649, 1).measure_hexadecimal()); assert_eq!(2, create_value(4294967294, 1).measure_hexadecimal()); assert_eq!(2, create_value(4294967295, 1).measure_hexadecimal()); assert_eq!(2, create_value(4294967296, 1).measure_hexadecimal()); assert_eq!(2, create_value(4294967297, 1).measure_hexadecimal()); assert_eq!(2, create_value(9223372036854775806, 1).measure_hexadecimal()); assert_eq!(2, create_value(9223372036854775807, 1).measure_hexadecimal()); assert_eq!(3, create_value(9223372036854775808, 1).measure_hexadecimal()); assert_eq!(3, create_value(9223372036854775809, 1).measure_hexadecimal()); assert_eq!(3, create_value(18446744073709551614, 1).measure_hexadecimal()); assert_eq!(3, create_value(18446744073709551615, 1).measure_hexadecimal()); assert_eq!(3, create_value(18446744073709551616, 1).measure_hexadecimal()); assert_eq!(3, create_value(18446744073709551617, 1).measure_hexadecimal()); assert_eq!(3, create_value(-18446744073709551616, 1).measure_hexadecimal()); assert_eq!(3, create_value(-18446744073709551615, 1).measure_hexadecimal()); assert_eq!(2, create_value(-9223372036854775808, 1).measure_hexadecimal()); assert_eq!(2, create_value(-9223372036854775807, 1).measure_hexadecimal()); assert_eq!(2, create_value(-4294967296, 1).measure_hexadecimal()); assert_eq!(2, create_value(-4294967295, 1).measure_hexadecimal()); assert_eq!(1, create_value(-2147483648, 1).measure_hexadecimal()); assert_eq!(1, create_value(-2147483647, 1).measure_hexadecimal()); assert_eq!(1, create_value(-2, 1).measure_hexadecimal()); assert_eq!(1, create_value(-1, 1).measure_hexadecimal()); }
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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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}