[wip] documentation for file module
This commit is contained in:
parent
61d62d731e
commit
5a34a8d791
3 changed files with 55 additions and 18 deletions
|
|
@ -54,6 +54,12 @@ impl Checked {
|
|||
}
|
||||
}
|
||||
|
||||
/// calculate and store hash for this file
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// - from `file::compute_hash`
|
||||
/// - Mismatch if file already hashed
|
||||
pub fn hash(&mut self, f: impl Fn(u64)) -> crate::Result<()> {
|
||||
if self.hash.is_some() {
|
||||
return Err(crate::Error::mismatch("unhashed file", self.path.display()));
|
||||
|
|
@ -64,15 +70,14 @@ impl Checked {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// start uploading this file
|
||||
/// starts uploading this file
|
||||
///
|
||||
/// - tries to create a new entry in a share
|
||||
/// - expects endpoint like `{base_uri}/alias/upload/{share_id}/files/tus`
|
||||
/// - tries to create a new file using the client
|
||||
/// - consumes `self` into a `file::Uploading` struct
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// TODO documentation after `ClientError` rework
|
||||
/// - from `sharry::Client::file_create`
|
||||
pub fn start_upload(
|
||||
self,
|
||||
client: &impl sharry::Client,
|
||||
|
|
@ -87,19 +92,15 @@ impl Checked {
|
|||
}
|
||||
|
||||
impl<'t> FileTrait<'t> for Checked {
|
||||
/// get a reference to the file's name
|
||||
///
|
||||
/// Uses `SharryFile::extract_file_name`, which may **panic**!
|
||||
fn get_name(&'t self) -> &'t str {
|
||||
<Self as FileTrait>::extract_file_name(&self.path)
|
||||
}
|
||||
|
||||
/// get the file's size
|
||||
fn get_size(&self) -> u64 {
|
||||
self.size
|
||||
}
|
||||
|
||||
fn check_hash(&self, on_progress: impl Fn(u64)) -> crate::Result<()> {
|
||||
fn check_hash(&self, on_progress: impl FnMut(u64)) -> crate::Result<()> {
|
||||
super::check_hash(
|
||||
&self.path,
|
||||
self.size,
|
||||
|
|
|
|||
|
|
@ -12,22 +12,38 @@ pub use chunk::Chunk;
|
|||
use log::{debug, warn};
|
||||
pub use uploading::Uploading;
|
||||
|
||||
/// how many bytes to hash at once (default: 4 MiB)
|
||||
const HASH_CHUNK_SIZE: usize = 4 * 1024 * 1024;
|
||||
|
||||
/// compute hash for a file given its path.
|
||||
/// Hash function: BLAKE2b, 512 bit
|
||||
///
|
||||
/// # Params
|
||||
///
|
||||
/// - `path` to the file to hash
|
||||
/// - `size` of that file
|
||||
/// - `on_progress` will be called for each processed chunk (max. `HASH_CHUNK_SIZE`)
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// - from `fs::File::open` and `fs::File::read`
|
||||
/// - Mismatch if given `size` does not match the file's size
|
||||
fn compute_hash(path: &Path, size: u64, mut on_progress: impl FnMut(u64)) -> crate::Result<String> {
|
||||
let mut file = fs::File::open(path)?;
|
||||
|
||||
// Blake2b-512 hasher (64 * 8 bit)
|
||||
let mut hasher = Blake2b::new().hash_length(64).to_state();
|
||||
|
||||
// buffer (4 MiB)
|
||||
let mut buf = vec![0; 4 * 1024 * 1024];
|
||||
// buffer
|
||||
let mut buffer = vec![0; HASH_CHUNK_SIZE];
|
||||
let mut bytes_read = 0;
|
||||
|
||||
loop {
|
||||
let n = file.read(&mut buf)?;
|
||||
let n = file.read(&mut buffer)?;
|
||||
if n == 0 {
|
||||
break;
|
||||
}
|
||||
hasher.update(&buf[..n]);
|
||||
hasher.update(&buffer[..n]);
|
||||
|
||||
// `buf` size must be < 2 EiB
|
||||
bytes_read += n as u64;
|
||||
|
|
@ -43,16 +59,32 @@ fn compute_hash(path: &Path, size: u64, mut on_progress: impl FnMut(u64)) -> cra
|
|||
Ok(result)
|
||||
}
|
||||
|
||||
/// check hash for a file given its path, return Ok(()) on success
|
||||
///
|
||||
/// # Params
|
||||
///
|
||||
/// - `path` to the file to hash
|
||||
/// - `size` of that file
|
||||
/// - optional known `hash`
|
||||
/// - `on_progress` will be called for each processed chunk (max. `HASH_CHUNK_SIZE`)
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// - from `file::compute_hash`
|
||||
/// - Mismatch if `hash` is `None`
|
||||
/// - Mismatch if given `hash` does not match the computed hash
|
||||
fn check_hash(
|
||||
path: &Path,
|
||||
size: u64,
|
||||
hash: Option<&str>,
|
||||
on_progress: impl FnMut(u64),
|
||||
) -> crate::Result<()> {
|
||||
// check if hash is None
|
||||
let Some(expected) = hash else {
|
||||
return Err(crate::Error::mismatch("hash", path.display()));
|
||||
};
|
||||
|
||||
// compute and check new hash
|
||||
let actual = &compute_hash(path, size, on_progress)?;
|
||||
|
||||
if expected == actual {
|
||||
|
|
@ -77,12 +109,19 @@ pub trait FileTrait<'t> {
|
|||
}
|
||||
|
||||
/// get a reference to the file's name
|
||||
///
|
||||
/// Uses `file::FileTrait::extract_file_name`, which may **panic**!
|
||||
fn get_name(&'t self) -> &'t str;
|
||||
|
||||
/// get the file's size
|
||||
fn get_size(&self) -> u64;
|
||||
|
||||
fn check_hash(&self, on_progress: impl Fn(u64)) -> crate::Result<()>;
|
||||
/// check this file's hash, return Ok(()) on success
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// - from `file::check_hash`
|
||||
fn check_hash(&self, on_progress: impl FnMut(u64)) -> crate::Result<()>;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
|||
|
|
@ -95,9 +95,6 @@ impl Uploading {
|
|||
}
|
||||
|
||||
impl<'t> FileTrait<'t> for Uploading {
|
||||
/// get a reference to the file's name
|
||||
///
|
||||
/// Uses `SharryFile::extract_file_name`, which may **panic**!
|
||||
fn get_name(&'t self) -> &'t str {
|
||||
<Self as FileTrait>::extract_file_name(&self.path)
|
||||
}
|
||||
|
|
@ -106,7 +103,7 @@ impl<'t> FileTrait<'t> for Uploading {
|
|||
self.size
|
||||
}
|
||||
|
||||
fn check_hash(&self, on_progress: impl Fn(u64)) -> crate::Result<()> {
|
||||
fn check_hash(&self, on_progress: impl FnMut(u64)) -> crate::Result<()> {
|
||||
super::check_hash(
|
||||
&self.path,
|
||||
self.size,
|
||||
|
|
|
|||
Loading…
Reference in a new issue