number.rs (1920B)
1 use crate::NumberToken; 2 3 #[derive(Debug, Clone, PartialEq)] 4 pub struct Number { 5 pub value: f64, 6 pub format: NumberFormat, 7 } 8 9 impl Number { 10 pub fn format(&self) -> String { 11 match self.format { 12 NumberFormat::Decimal => format!("{}", self.value), 13 NumberFormat::Scientific => format!("{:e}", self.value), 14 NumberFormat::Engineering => { 15 // Engineering notation adjusts exponent to be multiple of 3 16 let exp = self.value.abs().log10().floor(); 17 let adj_exp = (exp - exp % 3.0).floor(); 18 let coeff = self.value / 10_f64.powf(adj_exp); 19 format!("{}e{}", coeff, adj_exp) 20 } 21 } 22 } 23 } 24 25 #[derive(Debug, Default, Clone, PartialEq)] 26 pub enum NumberFormat { 27 #[default] 28 Decimal, 29 Scientific, 30 Engineering, 31 } 32 33 #[derive(Debug, Clone, Default)] 34 pub enum AngleMode { 35 Degrees, 36 #[default] 37 Radians, 38 } 39 40 #[derive(Clone)] 41 pub struct StandardNumber(pub f64); 42 43 impl NumberToken for StandardNumber { 44 fn value(&self) -> f64 { 45 self.0 46 } 47 48 fn format(&self) -> String { 49 format!("{}", self.0) 50 } 51 } 52 53 #[derive(Clone)] 54 pub struct ScientificNumber { 55 pub value: f64, 56 pub format: NumberFormat, 57 } 58 59 /// Different factory families can have different internal representations 60 impl NumberToken for ScientificNumber { 61 fn value(&self) -> f64 { 62 self.value 63 } 64 65 fn format(&self) -> String { 66 match self.format { 67 NumberFormat::Scientific => format!("{:e}", self.value), 68 NumberFormat::Engineering => { 69 let exp = self.value.abs().log10().floor(); 70 let adj_exp = (exp - exp % 3.0).floor(); 71 let coeff = self.value / 10_f64.powf(adj_exp); 72 format!("{}e{}", coeff, adj_exp) 73 } 74 _ => format!("{}", self.value), 75 } 76 } 77 }