Parse a decimal string (e.g. "999.99") into unscaled i128 with the given scale. For example, "999.99" with scale=2 → 99999; "0.000000000000000001" with scale=18 → 1.
(s: &str, scale: i8)
| 573 | /// Parse a decimal string (e.g. "999.99") into unscaled i128 with the given scale. |
| 574 | /// For example, "999.99" with scale=2 → 99999; "0.000000000000000001" with scale=18 → 1. |
| 575 | fn parse_decimal_string(s: &str, scale: i8) -> Option<i128> { |
| 576 | let negative = s.starts_with('-'); |
| 577 | let s = s.strip_prefix('-').unwrap_or(s); |
| 578 | let (integer_part, frac_part) = match s.find('.') { |
| 579 | Some(pos) => (&s[..pos], &s[pos + 1..]), |
| 580 | None => (s, ""), |
| 581 | }; |
| 582 | let frac_len = frac_part.len() as i8; |
| 583 | let combined = format!("{integer_part}{frac_part}"); |
| 584 | let unscaled: i128 = combined.parse().ok()?; |
| 585 | // Adjust if the fractional digits differ from the target scale. |
| 586 | let result = if frac_len < scale { |
| 587 | unscaled * 10i128.pow((scale - frac_len) as u32) |
| 588 | } else if frac_len > scale { |
| 589 | unscaled / 10i128.pow((frac_len - scale) as u32) |
| 590 | } else { |
| 591 | unscaled |
| 592 | }; |
| 593 | Some(if negative { -result } else { result }) |
| 594 | } |
| 595 | |
| 596 | /// Decode big-endian two's complement bytes into i128 (Avro decimal encoding). |
| 597 | fn bytes_to_i128_be(bytes: &[u8]) -> i128 { |
no test coverage detected