@@ -29,11 +29,12 @@ pub fn zip<P: StudentFilePolicy>(policy: P, root_directory: &Path) -> Result<Vec
2929 . unwrap_or_else ( || entry. path ( ) ) ;
3030 if entry. path ( ) . is_dir ( ) {
3131 log:: trace!( "adding directory {}" , path. display( ) ) ;
32- writer. add_directory ( path. to_string_lossy ( ) , FileOptions :: default ( ) ) ?;
32+ writer
33+ . add_directory ( path_to_zip_compatible_string ( path) , FileOptions :: default ( ) ) ?;
3334 } else {
3435 let bytes = file_util:: read_file ( entry. path ( ) ) ?;
3536 log:: trace!( "writing file {}" , path. display( ) ) ;
36- writer. start_file ( path . to_string_lossy ( ) , FileOptions :: default ( ) ) ?;
37+ writer. start_file ( path_to_zip_compatible_string ( path ) , FileOptions :: default ( ) ) ?;
3738 writer
3839 . write_all ( & bytes)
3940 . map_err ( |e| TmcError :: ZipWrite ( path. to_path_buf ( ) , e) ) ?;
@@ -44,6 +45,18 @@ pub fn zip<P: StudentFilePolicy>(policy: P, root_directory: &Path) -> Result<Vec
4445 Ok ( cursor. into_inner ( ) )
4546}
4647
48+ // ensures the / separator is used
49+ fn path_to_zip_compatible_string ( path : & Path ) -> String {
50+ let mut string = String :: new ( ) ;
51+ for component in path. components ( ) {
52+ if !string. is_empty ( ) {
53+ string. push ( '/' ) ;
54+ }
55+ string. push_str ( & * component. as_os_str ( ) . to_string_lossy ( ) ) ;
56+ }
57+ string
58+ }
59+
4760// todo: remove
4861/// Finds a project directory in the given zip and unzips it according to the given student policy. Also cleans unnecessary non-student files.
4962///
0 commit comments