@@ -12,45 +12,36 @@ use std::process::Command;
12
12
13
13
14
14
#[ derive( Clone , Debug , PartialEq ) ]
15
- pub enum GpsStringParseError
16
- {
15
+ pub enum GpsStringParseError {
17
16
NumberParseError ,
18
17
InvalidDirection ( String ) ,
19
- BadFormat
18
+ BadFormat ,
20
19
}
21
- impl std:: convert:: From < std:: num:: ParseFloatError > for GpsStringParseError
22
- {
23
- fn from ( _: std:: num:: ParseFloatError ) -> GpsStringParseError
24
- {
20
+ impl std:: convert:: From < std:: num:: ParseFloatError > for GpsStringParseError {
21
+ fn from ( _: std:: num:: ParseFloatError ) -> GpsStringParseError {
25
22
GpsStringParseError :: NumberParseError
26
23
}
27
24
}
28
- impl std:: convert:: From < std:: num:: ParseIntError > for GpsStringParseError
29
- {
30
- fn from ( _: std:: num:: ParseIntError ) -> GpsStringParseError
31
- {
25
+ impl std:: convert:: From < std:: num:: ParseIntError > for GpsStringParseError {
26
+ fn from ( _: std:: num:: ParseIntError ) -> GpsStringParseError {
32
27
GpsStringParseError :: NumberParseError
33
28
}
34
29
}
35
30
36
31
37
32
#[ derive( PartialEq , Debug ) ]
38
- pub enum CardinalDirection
39
- {
33
+ pub enum CardinalDirection {
40
34
East ,
41
35
West ,
42
36
North ,
43
- South
37
+ South ,
44
38
}
45
39
46
- impl std:: str:: FromStr for CardinalDirection
47
- {
40
+ impl std:: str:: FromStr for CardinalDirection {
48
41
type Err = GpsStringParseError ;
49
42
50
- fn from_str ( name : & str ) -> Result < CardinalDirection , GpsStringParseError >
51
- {
52
- match name
53
- {
43
+ fn from_str ( name : & str ) -> Result < CardinalDirection , GpsStringParseError > {
44
+ match name {
54
45
"N" => Ok ( CardinalDirection :: North ) ,
55
46
"S" => Ok ( CardinalDirection :: South ) ,
56
47
"W" => Ok ( CardinalDirection :: West ) ,
@@ -61,124 +52,111 @@ impl std::str::FromStr for CardinalDirection
61
52
}
62
53
63
54
#[ derive( PartialEq , Debug ) ]
64
- pub struct GpsCoordinate
65
- {
55
+ pub struct GpsCoordinate {
66
56
degrees : i16 ,
67
57
minutes : i16 ,
68
58
seconds : f32 ,
69
- direction : CardinalDirection
59
+ direction : CardinalDirection ,
70
60
}
71
61
72
- impl GpsCoordinate
73
- {
74
-
75
- pub fn new ( degrees : i16 , minutes : i16 , seconds : f32 , direction : CardinalDirection ) -> GpsCoordinate
76
- {
77
- GpsCoordinate {
62
+ impl GpsCoordinate {
63
+ pub fn new (
64
+ degrees : i16 ,
65
+ minutes : i16 ,
66
+ seconds : f32 ,
67
+ direction : CardinalDirection ,
68
+ ) -> GpsCoordinate {
69
+ GpsCoordinate {
78
70
degrees : degrees,
79
71
minutes : minutes,
80
72
seconds : seconds,
81
- direction : direction
73
+ direction : direction,
82
74
}
83
75
}
84
76
}
85
77
86
- impl std:: str:: FromStr for GpsCoordinate
87
- {
78
+ impl std:: str:: FromStr for GpsCoordinate {
88
79
type Err = GpsStringParseError ;
89
80
90
- fn from_str ( string : & str ) -> Result < GpsCoordinate , Self :: Err >
91
- {
81
+ fn from_str ( string : & str ) -> Result < GpsCoordinate , Self :: Err > {
92
82
lazy_static ! {
93
83
static ref RE : Regex = Regex :: new( "(\\ d*) deg (\\ d*)' (\\ d*.?\\ d*)\" ([NEWS])" ) . unwrap( ) ;
94
84
}
95
85
96
- match RE . captures_iter ( string) . next ( )
97
- {
98
- Some ( val) => Ok ( GpsCoordinate {
86
+ match RE . captures_iter ( string) . next ( ) {
87
+ Some ( val) => Ok ( GpsCoordinate {
99
88
degrees : val[ 1 ] . parse ( ) ?,
100
89
minutes : val[ 2 ] . parse ( ) ?,
101
90
seconds : val[ 3 ] . parse ( ) ?,
102
- direction : CardinalDirection :: from_str ( & val[ 4 ] ) ?
91
+ direction : CardinalDirection :: from_str ( & val[ 4 ] ) ?,
103
92
} ) ,
104
- None => Err ( GpsStringParseError :: BadFormat )
93
+ None => Err ( GpsStringParseError :: BadFormat ) ,
105
94
}
106
95
}
107
96
}
108
97
109
98
/**
110
99
A GPS location
111
100
*/
112
- pub struct Location
113
- {
101
+ pub struct Location {
114
102
longitude : GpsCoordinate ,
115
- latitude : GpsCoordinate
103
+ latitude : GpsCoordinate ,
116
104
}
117
- impl Location
118
- {
119
- pub fn new ( longitude : GpsCoordinate , latitude : GpsCoordinate ) -> Location
120
- {
105
+ impl Location {
106
+ pub fn new ( longitude : GpsCoordinate , latitude : GpsCoordinate ) -> Location {
121
107
Location {
122
108
longitude : longitude,
123
- latitude : latitude
109
+ latitude : latitude,
124
110
}
125
111
}
126
112
}
127
113
128
- pub struct ExifData
129
- {
130
- tags : HashMap < String , String >
114
+ pub struct ExifData {
115
+ tags : HashMap < String , String > ,
131
116
}
132
117
133
118
#[ derive( Debug ) ]
134
- pub enum ExifError
135
- {
119
+ pub enum ExifError {
136
120
InvalidGpsCoordinate ( GpsStringParseError ) ,
137
121
NoSuchTag ( String ) ,
138
122
MalformedDatetime ( String ) ,
139
123
IoError ( std:: io:: Error ) ,
140
- MalformedUtf8 ( std:: string:: FromUtf8Error )
124
+ MalformedUtf8 ( std:: string:: FromUtf8Error ) ,
141
125
}
142
- impl std:: convert:: From < std:: io:: Error > for ExifError
143
- {
144
- fn from ( e : std:: io:: Error ) -> ExifError
145
- {
126
+ impl std:: convert:: From < std:: io:: Error > for ExifError {
127
+ fn from ( e : std:: io:: Error ) -> ExifError {
146
128
ExifError :: IoError ( e)
147
129
}
148
130
}
149
- impl std:: convert:: From < std:: string:: FromUtf8Error > for ExifError
150
- {
151
- fn from ( e : std:: string:: FromUtf8Error ) -> ExifError
152
- {
131
+ impl std:: convert:: From < std:: string:: FromUtf8Error > for ExifError {
132
+ fn from ( e : std:: string:: FromUtf8Error ) -> ExifError {
153
133
ExifError :: MalformedUtf8 ( e)
154
134
}
155
135
}
156
136
157
137
158
138
159
- impl ExifData
160
- {
161
- pub fn from_exiftool_string ( data : & str ) -> Result < ExifData , ExifError >
162
- {
163
- let mut result = ExifData {
164
- tags : HashMap :: new ( )
139
+ impl ExifData {
140
+ pub fn from_exiftool_string ( data : & str ) -> Result < ExifData , ExifError > {
141
+ let mut result = ExifData {
142
+ tags : HashMap :: new ( ) ,
165
143
} ;
166
144
167
145
lazy_static ! {
168
146
static ref DATA_REGEX : Regex = Regex :: new( r"(.*\b)\s*: (.*)" ) . unwrap( ) ;
169
147
}
170
148
171
- for matches in DATA_REGEX . captures_iter ( data)
172
- {
149
+ for matches in DATA_REGEX . captures_iter ( data) {
173
150
//TODO: Handle erros here
174
- result. tags . insert ( String :: from ( & matches[ 1 ] ) , String :: from ( & matches[ 2 ] ) ) ;
151
+ result
152
+ . tags
153
+ . insert ( String :: from ( & matches[ 1 ] ) , String :: from ( & matches[ 2 ] ) ) ;
175
154
}
176
155
177
156
Ok ( result)
178
157
}
179
158
180
- pub fn from_file ( file : & str ) -> Result < ExifData , ExifError >
181
- {
159
+ pub fn from_file ( file : & str ) -> Result < ExifData , ExifError > {
182
160
let mut cmd = Command :: new ( "exiftool" ) ;
183
161
cmd. arg ( file) ;
184
162
@@ -191,45 +169,37 @@ impl ExifData
191
169
Self :: from_exiftool_string ( & command_output)
192
170
}
193
171
194
- pub fn get_tag ( & self , name : & str ) -> Option < & str >
195
- {
196
- match self . tags . get ( name)
197
- {
172
+ pub fn get_tag ( & self , name : & str ) -> Option < & str > {
173
+ match self . tags . get ( name) {
198
174
Some ( tag) => Some ( tag) ,
199
- None => None
175
+ None => None ,
200
176
}
201
177
}
202
178
203
- pub fn get_creation_date ( & self ) -> Result < chrono:: DateTime < chrono:: UTC > , ExifError >
204
- {
179
+ pub fn get_creation_date ( & self ) -> Result < chrono:: DateTime < chrono:: UTC > , ExifError > {
205
180
let target_tag = "Create Date" ;
206
- match self . get_tag ( target_tag)
207
- {
208
- Some ( date_string) =>
209
- {
181
+ match self . get_tag ( target_tag) {
182
+ Some ( date_string) => {
210
183
let parsed = chrono:: UTC . datetime_from_str ( date_string, "%Y:%m:%d %H:%M:%S" ) ;
211
184
212
- match parsed
213
- {
185
+ match parsed {
214
186
Ok ( result) => Ok ( result) ,
215
- _ => Err ( ExifError :: MalformedDatetime ( String :: from ( date_string) ) )
187
+ _ => Err ( ExifError :: MalformedDatetime ( String :: from ( date_string) ) ) ,
216
188
}
217
189
}
218
- None => Err ( ExifError :: NoSuchTag ( String :: from ( target_tag) ) )
190
+ None => Err ( ExifError :: NoSuchTag ( String :: from ( target_tag) ) ) ,
219
191
}
220
192
}
221
193
}
222
194
223
195
224
196
#[ cfg( test) ]
225
- mod exif_data_tests
226
- {
197
+ mod exif_data_tests {
227
198
use std:: str:: FromStr ;
228
199
use super :: * ;
229
200
230
201
#[ test]
231
- fn well_formed_file ( )
232
- {
202
+ fn well_formed_file ( ) {
233
203
let file_content = include_str ! ( "../test/files/exif1.txt" ) ;
234
204
235
205
let data = ExifData :: from_exiftool_string ( file_content) . unwrap ( ) ;
@@ -244,14 +214,13 @@ mod exif_data_tests
244
214
}
245
215
246
216
#[ test]
247
- fn gps_coordinate_test ( )
248
- {
217
+ fn gps_coordinate_test ( ) {
249
218
assert_eq ! (
250
- GpsCoordinate :: from_str( "58 deg 28' 5.45\" N" ) . unwrap( ) ,
219
+ GpsCoordinate :: from_str( "58 deg 28' 5.45\" N" ) . unwrap( ) ,
251
220
GpsCoordinate :: new( 58 , 28 , 5.45 , CardinalDirection :: North )
252
221
) ;
253
222
assert_eq ! (
254
- GpsCoordinate :: from_str( "58 deg 28' 5.45\" S" ) . unwrap( ) ,
223
+ GpsCoordinate :: from_str( "58 deg 28' 5.45\" S" ) . unwrap( ) ,
255
224
GpsCoordinate :: new( 58 , 28 , 5.45 , CardinalDirection :: South )
256
225
) ;
257
226
}
0 commit comments