11//! Types and constants for handling speed of rotation (angular velocity)
22
33use super :: measurement:: * ;
4- use :: PI ;
4+ #[ cfg( feature = "from_str" ) ]
5+ use regex:: Regex ;
6+ #[ cfg( feature = "from_str" ) ]
7+ use std:: str:: FromStr ;
8+ use PI ;
59
610/// The 'AngularVelocity' struct can be used to deal with angular velocities in a common way.
711///
@@ -69,6 +73,36 @@ impl Measurement for AngularVelocity {
6973 }
7074}
7175
76+ #[ cfg( feature = "from_str" ) ]
77+ impl FromStr for AngularVelocity {
78+ type Err = std:: num:: ParseFloatError ;
79+
80+ /// Create a new AngularVelocity from a string
81+ /// Plain numbers in string are considered to be radians per second
82+ fn from_str ( val : & str ) -> Result < Self , Self :: Err > {
83+ if val. is_empty ( ) {
84+ return Ok ( AngularVelocity :: from_radians_per_second ( 0.0 ) ) ;
85+ }
86+
87+ let re = Regex :: new ( r"(?i)\s*([0-9.]*)\s?([radspmhz/]{1,5})\s*$" ) . unwrap ( ) ;
88+ if let Some ( caps) = re. captures ( val) {
89+ let float_val = caps. get ( 1 ) . unwrap ( ) . as_str ( ) ;
90+ return Ok (
91+ match caps. get ( 2 ) . unwrap ( ) . as_str ( ) . to_lowercase ( ) . as_str ( ) {
92+ "rad/s" => AngularVelocity :: from_radians_per_second ( float_val. parse :: < f64 > ( ) ?) ,
93+ "rpm" => AngularVelocity :: from_rpm ( float_val. parse :: < f64 > ( ) ?) ,
94+ "hz" => AngularVelocity :: from_hertz ( float_val. parse :: < f64 > ( ) ?) ,
95+ _ => AngularVelocity :: from_radians_per_second ( val. parse :: < f64 > ( ) ?) ,
96+ } ,
97+ ) ;
98+ }
99+
100+ Ok ( AngularVelocity :: from_radians_per_second (
101+ val. parse :: < f64 > ( ) ?,
102+ ) )
103+ }
104+ }
105+
72106implement_measurement ! { AngularVelocity }
73107
74108#[ cfg( test) ]
@@ -85,4 +119,51 @@ mod test {
85119 assert_almost_eq ( r1, 628.31853 ) ;
86120 assert_almost_eq ( r2, 954.929659642538 ) ;
87121 }
122+
123+ #[ test]
124+ #[ cfg( feature = "from_str" ) ]
125+ fn empty_str ( ) {
126+ let t = AngularVelocity :: from_str ( "" ) ;
127+ assert ! ( t. is_ok( ) ) ;
128+
129+ let o = t. unwrap ( ) . as_radians_per_second ( ) ;
130+ assert_eq ! ( o, 0.0 ) ;
131+ }
132+
133+ #[ test]
134+ #[ cfg( feature = "from_str" ) ]
135+ fn rad_per_second_string ( ) {
136+ let t = AngularVelocity :: from_str ( "100 rad/s" ) ;
137+ assert ! ( t. is_ok( ) ) ;
138+
139+ let o = t. unwrap ( ) . as_radians_per_second ( ) ;
140+ assert_almost_eq ( o, 100.0 ) ;
141+ }
142+
143+ #[ test]
144+ #[ cfg( feature = "from_str" ) ]
145+ fn rpm_string ( ) {
146+ let t = AngularVelocity :: from_str ( "100rpm" ) ;
147+ assert ! ( t. is_ok( ) ) ;
148+
149+ let o = t. unwrap ( ) . as_rpm ( ) ;
150+ assert_almost_eq ( o, 100.0 ) ;
151+ }
152+
153+ #[ test]
154+ #[ cfg( feature = "from_str" ) ]
155+ fn hertz_string ( ) {
156+ let t = AngularVelocity :: from_str ( "100 Hz" ) ;
157+ assert ! ( t. is_ok( ) ) ;
158+
159+ let o = t. unwrap ( ) . as_hertz ( ) ;
160+ assert_almost_eq ( o, 100.0 ) ;
161+ }
162+
163+ #[ test]
164+ #[ cfg( feature = "from_str" ) ]
165+ fn invalid_str ( ) {
166+ let t = AngularVelocity :: from_str ( "abcd" ) ;
167+ assert ! ( t. is_err( ) ) ;
168+ }
88169}
0 commit comments