unc_gas/trait_impls/
from_str.rs1use crate::{UncGas, UncGasError, ONE_GIGA_GAS, ONE_TERA_GAS};
2
3impl std::str::FromStr for UncGas {
4 type Err = UncGasError;
5 fn from_str(s: &str) -> Result<Self, Self::Err> {
6 let uppercase_s = s.trim().to_ascii_uppercase();
7 let (value, unit) = uppercase_s.split_at(
8 s.find(|c: char| c.is_ascii_alphabetic())
9 .ok_or_else(|| UncGasError::IncorrectUnit(s.to_owned()))?,
10 );
11 let unit_precision = match unit {
12 "TGAS" | "TERAGAS" => ONE_TERA_GAS,
13 "GIGAGAS" | "GGAS" => ONE_GIGA_GAS,
14 _ => return Err(UncGasError::IncorrectUnit(s.to_owned())),
15 };
16 Ok(UncGas::from_gas(
17 crate::utils::parse_decimal_number(value.trim(), unit_precision)
18 .map_err(UncGasError::IncorrectNumber)?,
19 ))
20 }
21}
22
23#[cfg(test)]
24mod test {
25 use std::str::FromStr;
26
27 use crate::{DecimalNumberParsingError, UncGas, UncGasError};
28
29 #[test]
30 fn doubledot() {
31 let data = "1.1.1 TeraGas";
32 let gas: Result<UncGas, UncGasError> = FromStr::from_str(data);
33 assert_eq!(
34 gas,
35 Err(UncGasError::IncorrectNumber(
36 DecimalNumberParsingError::InvalidNumber("1.1.1".to_owned())
37 ))
38 )
39 }
40
41 #[test]
42 fn space_after_dot() {
43 let data = "1. 0 TeraGas";
44 let gas: Result<UncGas, UncGasError> = FromStr::from_str(data);
45 assert_eq!(
46 gas,
47 Err(UncGasError::IncorrectNumber(
48 DecimalNumberParsingError::InvalidNumber("1. 0".to_owned())
49 ))
50 )
51 }
52
53 #[test]
54 fn decimal_tgas() {
55 let data = "0.5 TGas";
56 let gas: Result<UncGas, UncGasError> = FromStr::from_str(data);
57 assert_eq!(gas, Ok(UncGas::from_ggas(500)))
58 }
59
60 #[test]
61 fn incorect_currency() {
62 let data = "0 pas";
63 let gas: Result<UncGas, UncGasError> = FromStr::from_str(data);
64 assert_eq!(gas, Err(UncGasError::IncorrectUnit(data.to_owned())))
65 }
66
67 #[test]
68 fn without_currency() {
69 let data = "0";
70 let gas: Result<UncGas, UncGasError> = FromStr::from_str(data);
71 assert_eq!(gas, Err(UncGasError::IncorrectUnit("0".to_owned())))
72 }
73
74 #[test]
75 fn invalid_whole() {
76 let data = "-1 TeraGas";
77 let gas: Result<UncGas, UncGasError> = FromStr::from_str(data);
78 assert_eq!(
79 gas,
80 Err(UncGasError::IncorrectNumber(
81 DecimalNumberParsingError::InvalidNumber("-1".to_owned())
82 ))
83 )
84 }
85
86 #[test]
87 fn test_from_str_f64_gas_without_int() {
88 let unc_gas = UncGas::from_str(".055ggas").unwrap_err();
89 assert_eq!(
90 unc_gas,
91 UncGasError::IncorrectNumber(DecimalNumberParsingError::InvalidNumber(
92 ".055".to_string()
93 ))
94 );
95 }
96
97 #[test]
98 fn test_from_str_without_unit() {
99 let unc_gas = UncGas::from_str("100").unwrap_err();
100 assert_eq!(unc_gas, UncGasError::IncorrectUnit("100".to_string()));
101 }
102
103 #[test]
104 fn test_from_str_incorrect_unit() {
105 let unc_gas = UncGas::from_str("100 UAH").unwrap_err();
106 assert_eq!(unc_gas, UncGasError::IncorrectUnit("100 UAH".to_string()));
107 }
108
109 #[test]
110 fn test_from_str_invalid_double_dot() {
111 let unc_gas = UncGas::from_str("100.55.").unwrap_err();
112 assert_eq!(unc_gas, UncGasError::IncorrectUnit("100.55.".to_string()));
113 }
114
115 #[test]
116 fn test_from_str_large_fractional_part() {
117 let unc_gas = UncGas::from_str("100.1111122222333 ggas").unwrap_err(); assert_eq!(
119 unc_gas,
120 UncGasError::IncorrectNumber(DecimalNumberParsingError::LongFractional(
121 "1111122222333".to_string()
122 ))
123 );
124 }
125
126 #[test]
127 fn test_from_str_large_int_part() {
128 let unc_gas = UncGas::from_str("200123456789123.0 tgas").unwrap_err();
129 assert_eq!(
130 unc_gas,
131 UncGasError::IncorrectNumber(DecimalNumberParsingError::LongWhole(
132 "200123456789123".to_string()
133 ))
134 );
135 }
136
137 #[test]
138 fn test_from_str_negative_value() {
139 let unc_gas = UncGas::from_str("-100 ggas").unwrap_err();
140 assert_eq!(
141 unc_gas,
142 UncGasError::IncorrectNumber(DecimalNumberParsingError::InvalidNumber(
143 "-100".to_string()
144 ))
145 );
146 }
147
148 #[test]
149 fn unc_gas_from_str_currency_tgas() {
150 assert_eq!(
151 UncGas::from_str("10 tgas").unwrap(),
152 UncGas::from_gas(10_000_000_000_000) );
154 assert_eq!(
155 UncGas::from_str("10.055TERAGAS").unwrap(),
156 UncGas::from_gas(10_055_000_000_000) );
158 }
159
160 #[test]
161 fn unc_gas_from_str_currency_gigagas() {
162 assert_eq!(
163 UncGas::from_str("10 gigagas").unwrap(),
164 UncGas::from_gas(10_000_000_000) );
166 assert_eq!(
167 UncGas::from_str("10GGAS ").unwrap(),
168 UncGas::from_gas(10_000_000_000) );
170 }
171
172 #[test]
173 fn unc_gas_from_str_f64_tgas() {
174 assert_eq!(
175 UncGas::from_str("0.000001 tgas").unwrap(),
176 UncGas::from_gas(1_000_000) );
178 }
179}