pub fn finalize_file(
    prefix: &str,
    hash: &str,
    target_path: &str,
    mode: Option<u32>,
    hash_chunk_size: usize,
) -> Result<(), ProtocolError> {
    // Double check that all the chunks of the file are present
    let (result, _) = validate_file(prefix, hash, None)?;

    if !result {
        return Err(ProtocolError::FinalizeError {
            cause: "file missing chunks".to_owned(),
        });
    }

    // Get the total number of chunks we're saving
    let (num_chunks, _, _) = load_meta(prefix, hash)?;

    // Q: Do we want to create the parent directories if they don't exist?
    let mut file = File::create(target_path).map_err(|err| ProtocolError::StorageError {
        action: format!("create/open file for writing {}", target_path),
        err,
    })?;

    // Set exported file's mode
    if let Some(mode_val) = mode {
        file.set_permissions(Permissions::from_mode(mode_val))
            .map_err(|err| ProtocolError::StorageError {
                action: "set target file's mode".to_owned(),
                err,
            })?;
    }

    // Iterate through chunks and reassemble file
    let mut load_chunk_err = None;
    for chunk_num in 0..num_chunks {
        let chunk = match load_chunk(prefix, hash, chunk_num) {
            Ok(c) => c,
            Err(e) => {
                warn!(
                    "Error encountered loading chunk {}, deleting : {}",
                    chunk_num, e
                );
                delete_chunk(prefix, hash, chunk_num)?;
                load_chunk_err = Some(e);
                continue;
            }
        };

        // Write the chunk to the destination file
        file.write_all(&chunk)
            .map_err(|err| ProtocolError::StorageError {
                action: format!("write chunk {}", chunk_num),
                err,
            })?;
    }

    if let Some(e) = load_chunk_err {
        return Err(e);
    }

    // Calculate hash of exported file
    let calc_hash_str = calc_file_hash(&target_path, hash_chunk_size)?;

    // Final determination if file was correctly received and assembled
    if calc_hash_str == hash {
        Ok(())
    } else {
        // If the hash doesn't match then we start over
        delete_file(&prefix, &hash)?;
        Err(ProtocolError::HashMismatch)
    }
}
// Export received chunks into final file and verify correct file hash
Export received chunks into final file and verify correct file hash
Export received chunks into final file and verify correct file hash
pub fn finalize_file(
    prefix: &str,
    hash: &str,
    target_path: &str,
    mode: Option<u32>,
    hash_chunk_size: usize,
) -> Result<(), ProtocolError> {
    // Double check that all the chunks of the file are present
    let (result, _) = validate_file(prefix, hash, None)?;
    if !result {
        return Err(ProtocolError::FinalizeError {
            cause: "file missing chunks".to_owned(),
        });
    }
    // Get the total number of chunks we're saving
    let (num_chunks, _, _) = load_meta(prefix, hash)?;
    // Q: Do we want to create the parent directories if they don't exist?
    let mut file = File::create(target_path).map_err(|err| ProtocolError::StorageError {
        action: format!("create/open file for writing {}", target_path),
        err,
    })?;
    // Set exported file's mode
    if let Some(mode_val) = mode {
        file.set_permissions(Permissions::from_mode(mode_val))
            .map_err(|err| ProtocolError::StorageError {
                action: "set target file's mode".to_owned(),
                err,
            })?;
    }
    // Iterate through chunks and reassemble file
    let mut load_chunk_err = None;
    for chunk_num in 0..num_chunks {
        let chunk = match load_chunk(prefix, hash, chunk_num) {
            Ok(c) => c,
            Err(e) => {
                warn!(
                    "Error encountered loading chunk {}, deleting : {}",
                    chunk_num, e
                );
                delete_chunk(prefix, hash, chunk_num)?;
                load_chunk_err = Some(e);
                continue;
            }
        };
        // Write the chunk to the destination file
        file.write_all(&chunk)
            .map_err(|err| ProtocolError::StorageError {
                action: format!("write chunk {}", chunk_num),
                err,
            })?;
    }
    if let Some(e) = load_chunk_err {
        return Err(e);
    }
    // Calculate hash of exported file
    let calc_hash_str = calc_file_hash(&target_path, hash_chunk_size)?;
    // Final determination if file was correctly received and assembled
    if calc_hash_str == hash {
        Ok(())
    } else {
        // If the hash doesn't match then we start over
        delete_file(&prefix, &hash)?;
        Err(ProtocolError::HashMismatch)
    }
}
pub fn finalize_file ( prefix : & str , hash : & str , target_path : & str , mode : Option < u32 > , hash_chunk_size : usize , ) -> Result < ( ) , ProtocolError > { // Double check that all the chunks of the file are present let ( result , _ ) = validate_file ( prefix , hash , None ) ? ; if ! result { return Err ( ProtocolError :: FinalizeError { cause : " " . to_owned ( ) , } ) ; } // Get the total number of chunks we're saving let ( num_chunks , _ , _ ) = load_meta ( prefix , hash ) ? ; // Q: Do we want to create the parent directories if they don't exist? let mut file = File :: create ( target_path ) . map_err ( | err | ProtocolError :: StorageError { action : format ! ( " " target_path ) , err , } ) ? ; // Set exported file's mode if let Some ( mode_val ) = mode { file . set_permissions ( Permissions :: from_mode ( mode_val ) ) . map_err ( | err | ProtocolError :: StorageError { action : " " . to_owned ( ) , err , } ) ? ; } // Iterate through chunks and reassemble file let mut load_chunk_err = None ; for chunk_num in 0 .. num_chunks { let chunk = match load_chunk ( prefix , hash , chunk_num ) { Ok ( c ) => c , Err ( e ) => { warn ! ( " " chunk_num e ) ; delete_chunk ( prefix , hash , chunk_num ) ? ; load_chunk_err = Some ( e ) ; continue ; } } ; // Write the chunk to the destination file file . write_all ( & chunk ) . map_err ( | err | ProtocolError :: StorageError { action : format ! ( " " chunk_num ) , err , } ) ? ; } if let Some ( e ) = load_chunk_err { return Err ( e ) ; } // Calculate hash of exported file let calc_hash_str = calc_file_hash ( & target_path , hash_chunk_size ) ? ; // Final determination if file was correctly received and assembled if calc_hash_str == hash { Ok ( ( ) ) } else { // If the hash doesn't match then we start over delete_file ( & prefix , & hash ) ? ; Err ( ProtocolError :: HashMismatch ) } }
Export received chunks into final file and verify correct file hash
Export received chunks into final file and verify correct file hash
prefix
&str
hash
&str
target_path
&str
mode
Option<u32>
hash_chunk_size
usize
prefix
&str
hash
&str
target_path
&str
mode
Option<u32>
hash_chunk_size
usize