@@ -347,13 +347,26 @@ fn extract_7z(archive: &PathBuf, dest: &PathBuf) -> Result<()> {
347347 . ok_or_else ( || Error :: Archive ( "Invalid destination path" . into ( ) ) ) ?;
348348 fs:: create_dir_all ( extract_to) ?;
349349
350+ // Track the top-level directory name from the archive
351+ let mut top_level_dir: Option < String > = None ;
352+
350353 reader
351354 . for_each_entries ( |entry, reader| {
355+ let entry_name = entry. name ( ) ;
356+
357+ // Capture the top-level directory name
358+ if top_level_dir. is_none ( )
359+ && let Some ( first_component) = entry_name. split ( '/' ) . next ( )
360+ && !first_component. is_empty ( )
361+ {
362+ top_level_dir = Some ( first_component. to_string ( ) ) ;
363+ }
364+
352365 if entry. is_directory ( ) {
353- let dir_path = extract_to. join ( entry . name ( ) ) ;
366+ let dir_path = extract_to. join ( entry_name ) ;
354367 fs:: create_dir_all ( & dir_path) . ok ( ) ;
355368 } else {
356- let file_path = extract_to. join ( entry . name ( ) ) ;
369+ let file_path = extract_to. join ( entry_name ) ;
357370 if let Some ( parent) = file_path. parent ( ) {
358371 fs:: create_dir_all ( parent) . ok ( ) ;
359372 }
@@ -364,8 +377,24 @@ fn extract_7z(archive: &PathBuf, dest: &PathBuf) -> Result<()> {
364377 } )
365378 . map_err ( |e| Error :: Archive ( e. to_string ( ) ) ) ?;
366379
367- // Move extracted contents to dest
368- fs:: create_dir_all ( dest) ?;
380+ // Rename extracted top-level directory to dest
381+ if let Some ( top_dir) = top_level_dir {
382+ let extracted_dir = extract_to. join ( & top_dir) ;
383+ if extracted_dir. exists ( ) && !dest. exists ( ) {
384+ fs:: rename ( & extracted_dir, dest) ?;
385+ } else if extracted_dir. exists ( ) && dest. exists ( ) {
386+ // If dest already exists, move contents
387+ for entry in fs:: read_dir ( & extracted_dir) ? {
388+ let entry = entry?;
389+ let dest_path = dest. join ( entry. file_name ( ) ) ;
390+ fs:: rename ( entry. path ( ) , dest_path) ?;
391+ }
392+ fs:: remove_dir_all ( & extracted_dir) ?;
393+ }
394+ } else {
395+ // No top-level directory, files extracted directly
396+ fs:: create_dir_all ( dest) ?;
397+ }
369398
370399 Ok ( ( ) )
371400}
0 commit comments