1
1
use std:: convert:: { From , TryFrom } ;
2
2
#[ cfg( not( test) ) ]
3
3
use std:: fs;
4
- use std:: path:: PathBuf ;
4
+ use std:: path:: { Path , PathBuf } ;
5
5
6
+ use crate :: commands:: log_to_file;
6
7
use crate :: environment:: make_subfolder_name_from_content;
7
8
use crate :: ffi:: conversion;
8
9
use crate :: file_path:: FilePath ;
9
10
use crate :: flags:: MapiFileFlags ;
10
11
use crate :: types:: * ;
11
12
13
+ const FALLBACK_TMP_SUBDIR_PATH : & str = "xxxxxxxx" ;
14
+
12
15
#[ repr( C ) ]
13
16
#[ derive( Debug ) ]
14
17
pub struct RawMapiFileTagExt {
@@ -142,7 +145,6 @@ impl FileDescriptor {
142
145
/// tmp_path + basename(self.path_name) otherwise.
143
146
///
144
147
/// return the path that points to the file to be attached
145
- #[ cfg( not( test) ) ]
146
148
pub fn consolidate_into ( & self , tmp_path : & Option < PathBuf > ) -> PathBuf {
147
149
if tmp_path. is_some ( ) {
148
150
let trg_path_cloned = tmp_path. as_ref ( ) . unwrap ( ) . clone ( ) ;
@@ -152,43 +154,95 @@ impl FileDescriptor {
152
154
} else {
153
155
self . path_name . file_name ( ) . into ( )
154
156
} ;
155
- let sub_name = make_subfolder_name_from_content ( & self . path_name )
156
- . unwrap_or_else ( |_| "xxxxxxxx" . to_owned ( ) ) ;
157
- let new_path = trg_path_cloned. join ( sub_name) . join ( trg_name_cloned) ;
158
- if fs:: copy ( & self . path_name , & new_path) . is_ok ( ) {
157
+
158
+ if let Some ( new_path) = self . copy_file_to_tmp_subdir ( & trg_path_cloned, & trg_name_cloned)
159
+ {
159
160
return new_path;
160
161
}
161
162
}
162
163
163
164
self . path_name . clone ( ) . into ( )
164
165
}
165
166
166
- #[ cfg( test) ]
167
- pub fn consolidate_into ( & self , tmp_path : & Option < PathBuf > ) -> PathBuf {
168
- if tmp_path . is_some ( ) {
169
- let trg_path_cloned = tmp_path . as_ref ( ) . unwrap ( ) . clone ( ) ;
170
- let trg_name_cloned = if self . needs_new_name ( ) {
171
- // unwrap is OK because needs_new_name returns false when file_name is None.
172
- self . file_name . as_ref ( ) . unwrap ( ) . clone ( )
173
- } else {
174
- self . path_name . file_name ( ) . into ( )
175
- } ;
176
- let new_path = trg_path_cloned . join ( & "xxxxxxxx" ) . join ( trg_name_cloned ) ;
177
- return new_path ;
167
+ #[ cfg( not ( test) ) ]
168
+ fn copy_file_to_tmp_subdir ( & self , tmp_path : & Path , tmp_name : & Path ) -> Option < PathBuf > {
169
+ let sub_name = make_subfolder_name_from_content ( & self . path_name )
170
+ . unwrap_or_else ( |_| FALLBACK_TMP_SUBDIR_PATH . to_owned ( ) ) ;
171
+ let tmp_subdir_path = tmp_path . join ( sub_name ) ;
172
+
173
+ if fs :: create_dir_all ( & tmp_subdir_path ) . is_err ( ) {
174
+ log_to_file (
175
+ "FileDescriptor::copy_file_to_tmp_subdir" ,
176
+ "failed to create temporary directory for attachment" ,
177
+ ) ;
178
+ return None ;
178
179
}
179
180
180
- self . path_name . clone ( ) . into ( )
181
+ let dest = tmp_subdir_path. join ( tmp_name) ;
182
+
183
+ if fs:: copy ( & self . path_name , & dest) . is_err ( ) {
184
+ log_to_file (
185
+ "FileDescriptor::copy_file_to_tmp_subdir" ,
186
+ "failed to copy file" ,
187
+ ) ;
188
+ return None ;
189
+ }
190
+
191
+ Some ( dest)
192
+ }
193
+
194
+ #[ cfg( test) ]
195
+ fn copy_file_to_tmp_subdir ( & self , tmp_path : & PathBuf , tmp_name : & PathBuf ) -> Option < PathBuf > {
196
+ Some ( tmp_path. join ( FALLBACK_TMP_SUBDIR_PATH ) . join ( tmp_name) )
181
197
}
182
198
}
183
199
184
200
#[ cfg( test) ]
185
201
mod tests {
202
+ use std:: path:: PathBuf ;
203
+
204
+ use crate :: structs:: file_descriptor:: FALLBACK_TMP_SUBDIR_PATH ;
186
205
use crate :: structs:: FileDescriptor ;
187
206
188
207
#[ test]
189
208
fn needs_new_name_works ( ) {
190
- assert ! ( !FileDescriptor :: new( & "C:\\ hello.txt" , Some ( "hello.txt" ) ) . needs_new_name( ) ) ;
191
209
assert ! ( FileDescriptor :: new( & "C:\\ hello.txt" , Some ( "ciao.txt" ) ) . needs_new_name( ) ) ;
210
+
211
+ assert ! ( !FileDescriptor :: new( & "C:\\ hello.txt" , Some ( "hello.txt" ) ) . needs_new_name( ) ) ;
192
212
assert ! ( !FileDescriptor :: new( & "C:\\ hello.txt" , None ) . needs_new_name( ) ) ;
193
213
}
214
+
215
+ #[ test]
216
+ // TODO test the case where copying the file fails (would require some kind of refactoring, or just a static variable hack)
217
+ fn consolidate_into_works ( ) {
218
+ assert_eq ! (
219
+ FileDescriptor :: new( & "C:\\ User\\ Doccies\\ hello.txt" , Some ( "hello.txt" ) )
220
+ . consolidate_into( & Some ( "C:\\ User\\ TmpDir" . into( ) ) ) ,
221
+ PathBuf :: from( format!(
222
+ "C:\\ User\\ TmpDir\\ {}\\ hello.txt" ,
223
+ FALLBACK_TMP_SUBDIR_PATH
224
+ ) ) ,
225
+ "If the same file name is given, then it is copied with the same filename"
226
+ ) ;
227
+
228
+ assert_eq ! (
229
+ FileDescriptor :: new( & "C:\\ User\\ Doccies\\ hello.txt" , Some ( "ciao.txt" ) )
230
+ . consolidate_into( & Some ( "C:\\ User\\ TmpDir" . into( ) ) ) ,
231
+ PathBuf :: from( format!(
232
+ "C:\\ User\\ TmpDir\\ {}\\ ciao.txt" ,
233
+ FALLBACK_TMP_SUBDIR_PATH
234
+ ) ) ,
235
+ "If a different file name is given, then it copies with the new filename" ,
236
+ ) ;
237
+
238
+ assert_eq ! (
239
+ FileDescriptor :: new( & "C:\\ User\\ Doccies\\ hello.txt" , None )
240
+ . consolidate_into( & Some ( "C:\\ User\\ TmpDir" . into( ) ) ) ,
241
+ PathBuf :: from( format!(
242
+ "C:\\ User\\ TmpDir\\ {}\\ hello.txt" ,
243
+ FALLBACK_TMP_SUBDIR_PATH
244
+ ) ) ,
245
+ "If no file name is given, then it copies with the original filename"
246
+ ) ;
247
+ }
194
248
}
0 commit comments