Skip to content

Commit be66d17

Browse files
drodileldruin
authored andcommitted
Add support to create Acceleration from string
Again behind the from_str feature. Tests included.
1 parent fc72bb6 commit be66d17

File tree

1 file changed

+101
-2
lines changed

1 file changed

+101
-2
lines changed

src/acceleration.rs

Lines changed: 101 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
//! Types and constants for handling acceleration.
22
3-
use super::measurement::*;
43
use super::length;
4+
use super::measurement::*;
5+
#[cfg(feature = "from_str")]
6+
use regex::Regex;
7+
#[cfg(feature = "from_str")]
8+
use std::str::FromStr;
59

610
/// The `Acceleration` struct can be used to deal with Accelerations in a common way.
711
/// Common metric and imperial units are supported.
@@ -78,14 +82,47 @@ impl Measurement for Acceleration {
7882
}
7983
}
8084

85+
#[cfg(feature = "from_str")]
86+
impl FromStr for Acceleration {
87+
type Err = std::num::ParseFloatError;
88+
89+
/// Create a new Acceleration from a string
90+
/// Plain numbers in string are considered to be meters per second
91+
fn from_str(val: &str) -> Result<Self, Self::Err> {
92+
if val.is_empty() {
93+
return Ok(Acceleration::from_metres_per_second_per_second(0.0));
94+
}
95+
96+
let re = Regex::new(r"(?i)\s*([0-9.]*)\s?([ftmps -1]{1,6})\s*$").unwrap();
97+
if let Some(caps) = re.captures(val) {
98+
let float_val = caps.get(1).unwrap().as_str();
99+
return Ok(
100+
match caps.get(2).unwrap().as_str().to_lowercase().as_str() {
101+
"m/s" | "m s-1" => {
102+
Acceleration::from_meters_per_second_per_second(float_val.parse::<f64>()?)
103+
}
104+
"ft/s" | "fps" | "ft s-1" => {
105+
Acceleration::from_feet_per_second_per_second(float_val.parse::<f64>()?)
106+
}
107+
_ => Acceleration::from_meters_per_second_per_second(val.parse::<f64>()?),
108+
},
109+
);
110+
}
111+
112+
Ok(Acceleration::from_meters_per_second_per_second(
113+
val.parse::<f64>()?,
114+
))
115+
}
116+
}
117+
81118
implement_measurement! { Acceleration }
82119

83120
#[cfg(test)]
84121
mod test {
85122

86123
use super::*;
87-
use test_utils::assert_almost_eq;
88124
use speed::Speed;
125+
use test_utils::assert_almost_eq;
89126

90127
// Metric
91128
#[test]
@@ -158,4 +195,66 @@ mod test {
158195
assert_eq!(a > b, false);
159196
assert_eq!(a >= b, false);
160197
}
198+
199+
#[test]
200+
#[cfg(feature = "from_str")]
201+
fn meters_per_second_str() {
202+
let t = Acceleration::from_str(" 12.0m/s");
203+
assert!(t.is_ok());
204+
let o = t.unwrap().as_meters_per_second_per_second();
205+
assert_almost_eq(12.0, o);
206+
}
207+
208+
#[test]
209+
#[cfg(feature = "from_str")]
210+
fn meters_per_second_minus_str() {
211+
let t = Acceleration::from_str("12.0 m s-1");
212+
assert!(t.is_ok());
213+
let o = t.unwrap().as_meters_per_second_per_second();
214+
assert_almost_eq(12.0, o);
215+
}
216+
217+
#[test]
218+
#[cfg(feature = "from_str")]
219+
fn feet_per_second_str() {
220+
let t = Acceleration::from_str(" 12.0ft/s");
221+
assert!(t.is_ok());
222+
let o = t.unwrap().as_feet_per_second_per_second();
223+
assert_almost_eq(12.0, o);
224+
}
225+
226+
#[test]
227+
#[cfg(feature = "from_str")]
228+
fn feet_per_second_fps_str() {
229+
let t = Acceleration::from_str(" 12.0fps");
230+
assert!(t.is_ok());
231+
let o = t.unwrap().as_feet_per_second_per_second();
232+
assert_almost_eq(12.0, o);
233+
}
234+
235+
#[test]
236+
#[cfg(feature = "from_str")]
237+
fn feet_per_second_minus_str() {
238+
let t = Acceleration::from_str("12.0 ft s-1");
239+
assert!(t.is_ok());
240+
let o = t.unwrap().as_feet_per_second_per_second();
241+
assert_almost_eq(12.0, o);
242+
}
243+
244+
#[test]
245+
#[cfg(feature = "from_str")]
246+
fn number_str() {
247+
let t = Acceleration::from_str("100.5");
248+
assert!(t.is_ok());
249+
250+
let o = t.unwrap().as_meters_per_second_per_second();
251+
assert_almost_eq(o, 100.5);
252+
}
253+
254+
#[test]
255+
#[cfg(feature = "from_str")]
256+
fn invalid_str() {
257+
let t = Acceleration::from_str("abcd");
258+
assert!(t.is_err());
259+
}
161260
}

0 commit comments

Comments
 (0)