1
1
//! Types and constants for handling speed of rotation (angular velocity)
2
2
3
3
use 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 ;
5
9
6
10
/// The 'AngularVelocity' struct can be used to deal with angular velocities in a common way.
7
11
///
@@ -69,6 +73,36 @@ impl Measurement for AngularVelocity {
69
73
}
70
74
}
71
75
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
+
72
106
implement_measurement ! { AngularVelocity }
73
107
74
108
#[ cfg( test) ]
@@ -85,4 +119,51 @@ mod test {
85
119
assert_almost_eq ( r1, 628.31853 ) ;
86
120
assert_almost_eq ( r2, 954.929659642538 ) ;
87
121
}
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
+ }
88
169
}
0 commit comments