sudachi/plugin/path_rewrite/join_numeric/numeric_parser/
string_number.rs1#[derive(Debug)]
18pub struct StringNumber {
19 significand: String,
20 scale: usize,
21 point: i32,
22 pub is_all_zero: bool,
23}
24
25impl StringNumber {
26 pub fn new() -> StringNumber {
27 StringNumber {
28 significand: String::new(),
29 scale: 0,
30 point: -1,
31 is_all_zero: true,
32 }
33 }
34
35 pub fn clear(&mut self) {
36 self.significand.clear();
37 self.scale = 0;
38 self.point = -1;
39 self.is_all_zero = true;
40 }
41
42 pub fn append(&mut self, i: i32) {
43 if i != 0 {
44 self.is_all_zero = false;
45 }
46 self.significand += &i.to_string();
47 }
48
49 pub fn shift_scale(&mut self, i: i32) {
50 if self.is_zero() {
51 self.significand += "1";
52 }
53 self.scale = (self.scale as i32 + i) as usize;
54 }
55
56 pub fn add(&mut self, number: &mut StringNumber) -> bool {
57 if number.is_zero() {
58 return true;
59 }
60
61 if self.is_zero() {
62 self.significand += &number.significand;
63 self.scale = number.scale;
64 self.point = number.point;
65 return true;
66 }
67
68 self.normalize_scale();
69 let length = number.int_length();
70 if self.scale >= length {
71 self.fill_zero(self.scale - length);
72 if number.point >= 0 {
73 self.point = self.significand.len() as i32 + number.point;
74 }
75 self.significand += &number.significand;
76 self.scale = number.scale;
77 return true;
78 }
79
80 false
81 }
82
83 pub fn set_point(&mut self) -> bool {
84 if self.scale == 0 && self.point < 0 {
85 self.point = self.significand.len() as i32;
86 return true;
87 }
88 false
89 }
90
91 fn int_length(&mut self) -> usize {
92 self.normalize_scale();
93 if self.point >= 0 {
94 return self.point as usize;
95 }
96 self.significand.len() + self.scale
97 }
98
99 pub fn is_zero(&self) -> bool {
100 self.significand.is_empty()
101 }
102
103 pub fn to_string(&mut self) -> String {
104 if self.is_zero() {
105 return "0".to_owned();
106 }
107
108 self.normalize_scale();
109 if self.scale > 0 {
110 self.fill_zero(self.scale);
111 } else if self.point >= 0 {
112 self.significand.insert(self.point as usize, '.');
113 if self.point == 0 {
114 self.significand.insert(0, '0');
115 }
116 let n_last_zero = self
117 .significand
118 .chars()
119 .rev()
120 .take_while(|c| *c == '0')
121 .count();
122 self.significand
123 .truncate(self.significand.len() - n_last_zero);
124 if self.significand.ends_with('.') {
125 self.significand.truncate(self.significand.len() - 1);
126 }
127 }
128
129 self.significand.clone()
130 }
131
132 fn normalize_scale(&mut self) {
133 if self.point >= 0 {
134 let n_scale = self.significand.len() as i32 - self.point;
135 if n_scale > self.scale as i32 {
136 self.point += self.scale as i32;
137 self.scale = 0;
138 } else {
139 self.scale -= n_scale as usize;
140 self.point = -1;
141 }
142 }
143 }
144
145 fn fill_zero(&mut self, length: usize) {
146 self.significand += &"0".repeat(length);
147 }
148}