1use cas_parser::parser::ast::literal::DIGITS;
4use rug::{ops::Pow, Assign, Complex, Float, Integer};
5
6pub const PRECISION: u32 = 1 << 9;
8
9pub fn int<T>(n: T) -> Integer
11where
12 Integer: From<T>,
13{
14 Integer::from(n)
15}
16
17pub fn int_from_float(f: Float) -> Integer {
19 f.trunc().to_integer().unwrap()
21}
22
23pub fn int_from_str(s: &str) -> Integer {
25 Integer::from_str_radix(s, 10).unwrap()
26}
27
28pub fn float<T>(n: T) -> Float
30where
31 Float: Assign<T>,
32{
33 Float::with_val(PRECISION, n)
34}
35
36pub fn float_from_str(s: &str) -> Float {
38 Float::with_val(PRECISION, Float::parse(s).unwrap())
39}
40
41pub fn from_str_radix(s: &str, radix: u8) -> Integer {
46 let mut result = int(0);
47 let allowed_digits = &DIGITS[..radix as usize];
48
49 let radix = int(radix);
50 for (i, c) in s.chars().rev().enumerate() {
51 let digit = int(allowed_digits.iter().position(|&d| d == c).unwrap());
52 result += digit * int((&radix).pow(i as u32));
53 }
54
55 result
56}
57
58pub fn complex<T>(n: T) -> Complex
60where
61 Complex: Assign<T>,
62{
63 Complex::with_val(PRECISION, n)
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69
70 #[test]
71 fn radix_eval() {
72 let expected = 1072.0;
73 let numbers = [
74 (2, "10000110000"),
75 (8, "2060"),
76 (25, "1hm"),
77 (32, "11g"),
78 (47, "mC"),
79 ];
80
81 for (radix, number) in numbers.iter() {
82 assert_eq!(from_str_radix(number, *radix), expected);
83 }
84 }
85}