[wip] documentation and minor refactoring
This commit is contained in:
parent
6ba17d57df
commit
7b3516df4c
7 changed files with 70 additions and 40 deletions
2
.vscode/tasks.json
vendored
2
.vscode/tasks.json
vendored
|
|
@ -70,7 +70,7 @@
|
||||||
"command": "echo All Tests successful!",
|
"command": "echo All Tests successful!",
|
||||||
"dependsOn": [
|
"dependsOn": [
|
||||||
"Run Unit Tests",
|
"Run Unit Tests",
|
||||||
"Run Integration Tests"
|
// "Run Integration Tests"
|
||||||
],
|
],
|
||||||
"dependsOrder": "sequence",
|
"dependsOrder": "sequence",
|
||||||
"group": "test"
|
"group": "test"
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ impl CacheFile {
|
||||||
.take()
|
.take()
|
||||||
.expect("abort_upload called while not uploading");
|
.expect("abort_upload called while not uploading");
|
||||||
|
|
||||||
self.files.push_front(upl.abort());
|
self.files.push_front(upl.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn share_notify(&self, client: &impl Client) -> crate::Result<()> {
|
pub fn share_notify(&self, client: &impl Client) -> crate::Result<()> {
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,11 @@ use super::{FileTrait, Uploading};
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub struct Checked {
|
pub struct Checked {
|
||||||
/// canonical path to a regular file
|
/// canonical path to a regular file
|
||||||
pub(super) path: PathBuf,
|
path: PathBuf,
|
||||||
/// size of that file
|
/// size of that file
|
||||||
pub(super) size: u64,
|
size: u64,
|
||||||
/// hash of that file
|
/// hash of that file
|
||||||
pub(super) hash: Option<String>,
|
hash: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsRef<[u8]> for Checked {
|
impl AsRef<[u8]> for Checked {
|
||||||
|
|
@ -32,6 +32,10 @@ impl AsRef<[u8]> for Checked {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Checked {
|
impl Checked {
|
||||||
|
pub(super) fn new_direct(path: PathBuf, size: u64, hash: Option<String>) -> Self {
|
||||||
|
Self { path, size, hash }
|
||||||
|
}
|
||||||
|
|
||||||
/// create a new checked file from some path reference
|
/// create a new checked file from some path reference
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
|
|
@ -70,10 +74,10 @@ impl Checked {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// starts uploading this file
|
/// start uploading this file
|
||||||
///
|
///
|
||||||
/// - tries to create a new file using the client
|
/// - try to create a new file using the client
|
||||||
/// - consumes `self` into a `file::Uploading` struct
|
/// - consume `self` into a `file::Uploading` struct
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
|
|
@ -87,7 +91,9 @@ impl Checked {
|
||||||
) -> crate::Result<Uploading> {
|
) -> crate::Result<Uploading> {
|
||||||
let file_id = client.file_create(uri, alias_id, share_id, &self)?;
|
let file_id = client.file_create(uri, alias_id, share_id, &self)?;
|
||||||
|
|
||||||
Ok(Uploading::new(self.path, self.size, self.hash, file_id))
|
Ok(Uploading::new_direct(
|
||||||
|
self.path, self.size, self.hash, file_id,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -101,11 +107,6 @@ impl FileTrait for Checked {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_hash(&self, on_progress: impl FnMut(u64)) -> crate::Result<()> {
|
fn check_hash(&self, on_progress: impl FnMut(u64)) -> crate::Result<()> {
|
||||||
super::check_hash(
|
super::check_hash(&self.path, self.size, self.hash.as_deref(), on_progress)
|
||||||
&self.path,
|
|
||||||
self.size,
|
|
||||||
self.hash.as_deref(),
|
|
||||||
on_progress,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ impl fmt::Debug for Chunk<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'t> Chunk<'t> {
|
impl<'t> Chunk<'t> {
|
||||||
pub fn new(file_id: sharry::FileID, offset: u64, data: &'t [u8]) -> Self {
|
pub(super) fn new_direct(file_id: sharry::FileID, offset: u64, data: &'t [u8]) -> Self {
|
||||||
Self {
|
Self {
|
||||||
file_id,
|
file_id,
|
||||||
offset,
|
offset,
|
||||||
|
|
@ -39,7 +39,7 @@ impl<'t> Chunk<'t> {
|
||||||
self.data
|
self.data
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_length(&self) -> u64 {
|
pub(super) fn get_length(&self) -> u64 {
|
||||||
let len = self.data.len();
|
let len = self.data.len();
|
||||||
|
|
||||||
// BOOKMARK this might **panic** on platforms where `usize` has more than 64 bit.
|
// BOOKMARK this might **panic** on platforms where `usize` has more than 64 bit.
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ const HASH_CHUNK_SIZE: usize = 4 * 1024 * 1024;
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
/// - from `fs::File::open` and `fs::File::read`
|
/// - from `fs::File::{open, read}`
|
||||||
/// - Mismatch if given `size` does not match the file's size
|
/// - 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> {
|
fn compute_hash(path: &Path, size: u64, mut on_progress: impl FnMut(u64)) -> crate::Result<String> {
|
||||||
let mut file = fs::File::open(path)?;
|
let mut file = fs::File::open(path)?;
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,10 @@ use crate::sharry;
|
||||||
|
|
||||||
use super::{Checked, Chunk, FileTrait};
|
use super::{Checked, Chunk, FileTrait};
|
||||||
|
|
||||||
|
/// Description of a `file::Checked` that is actively being uploaded
|
||||||
|
///
|
||||||
|
/// - impl `serde` for cachefile handling
|
||||||
|
/// - impl `Into<Checked>` to abort an upload
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub struct Uploading {
|
pub struct Uploading {
|
||||||
/// canonical path to a regular file
|
/// canonical path to a regular file
|
||||||
|
|
@ -19,14 +23,23 @@ pub struct Uploading {
|
||||||
size: u64,
|
size: u64,
|
||||||
/// hash of that file
|
/// hash of that file
|
||||||
hash: Option<String>,
|
hash: Option<String>,
|
||||||
|
/// file ID in a Sharry share
|
||||||
file_id: sharry::FileID,
|
file_id: sharry::FileID,
|
||||||
|
/// previous offset, if applicable
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
last_offset: Option<u64>,
|
previous_offset: Option<u64>,
|
||||||
|
/// current reading offset
|
||||||
offset: u64,
|
offset: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<Uploading> for Checked {
|
||||||
|
fn from(value: Uploading) -> Self {
|
||||||
|
Self::new_direct(value.path, value.size, value.hash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Uploading {
|
impl Uploading {
|
||||||
pub(super) fn new(
|
pub(super) fn new_direct(
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
size: u64,
|
size: u64,
|
||||||
hash: Option<String>,
|
hash: Option<String>,
|
||||||
|
|
@ -37,19 +50,25 @@ impl Uploading {
|
||||||
size,
|
size,
|
||||||
hash,
|
hash,
|
||||||
file_id,
|
file_id,
|
||||||
last_offset: None,
|
previous_offset: None,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// get the current reading offset
|
||||||
pub fn get_offset(&self) -> u64 {
|
pub fn get_offset(&self) -> u64 {
|
||||||
self.offset
|
self.offset
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// rewind to the previously read chunk
|
||||||
|
///
|
||||||
|
/// - consume self, returning Some(self) on success
|
||||||
|
///
|
||||||
|
/// # TODO this should take &mut self and return `crate::Result<()>`
|
||||||
pub fn rewind(mut self) -> Option<Self> {
|
pub fn rewind(mut self) -> Option<Self> {
|
||||||
if let Some(last_offset) = self.last_offset {
|
if let Some(offset) = self.previous_offset.take() {
|
||||||
self.last_offset = None;
|
self.offset = offset;
|
||||||
self.offset = last_offset;
|
|
||||||
Some(self)
|
Some(self)
|
||||||
} else {
|
} else {
|
||||||
warn!("attempted to rewind twice");
|
warn!("attempted to rewind twice");
|
||||||
|
|
@ -57,6 +76,14 @@ impl Uploading {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// read the next chunk
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// - from `fs::File::{open, seek, read}`
|
||||||
|
/// - `UnexpectedEof` if `read` returned no bytes
|
||||||
|
///
|
||||||
|
/// # TODO this should return `crate::Result<Chunk<'t>>`
|
||||||
pub fn read<'t>(&mut self, buf: &'t mut [u8]) -> io::Result<Chunk<'t>> {
|
pub fn read<'t>(&mut self, buf: &'t mut [u8]) -> io::Result<Chunk<'t>> {
|
||||||
let mut f = fs::File::open(&self.path)?;
|
let mut f = fs::File::open(&self.path)?;
|
||||||
|
|
||||||
|
|
@ -70,13 +97,18 @@ impl Uploading {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let chunk = Chunk::new(self.file_id.clone(), self.offset, &buf[..read_len]);
|
let chunk = Chunk::new_direct(self.file_id.clone(), self.offset, &buf[..read_len]);
|
||||||
self.last_offset = Some(self.offset);
|
self.previous_offset = Some(self.offset);
|
||||||
self.offset += chunk.get_length();
|
self.offset += chunk.get_length();
|
||||||
|
|
||||||
Ok(chunk)
|
Ok(chunk)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// check if this file has been completely read
|
||||||
|
///
|
||||||
|
/// - consume self, returning Ok(self) if EOF not reached, Err(PathBuf) otherwise
|
||||||
|
///
|
||||||
|
/// # TODO factor this into `read` and something more explicit like `finish(self) -> PathBuf`
|
||||||
pub fn check_eof(self) -> Result<Self, PathBuf> {
|
pub fn check_eof(self) -> Result<Self, PathBuf> {
|
||||||
if self.offset < self.size {
|
if self.offset < self.size {
|
||||||
Ok(self)
|
Ok(self)
|
||||||
|
|
@ -84,14 +116,6 @@ impl Uploading {
|
||||||
Err(self.path)
|
Err(self.path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn abort(self) -> Checked {
|
|
||||||
Checked {
|
|
||||||
path: self.path,
|
|
||||||
size: self.size,
|
|
||||||
hash: self.hash,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileTrait for Uploading {
|
impl FileTrait for Uploading {
|
||||||
|
|
@ -104,11 +128,6 @@ impl FileTrait for Uploading {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_hash(&self, on_progress: impl FnMut(u64)) -> crate::Result<()> {
|
fn check_hash(&self, on_progress: impl FnMut(u64)) -> crate::Result<()> {
|
||||||
super::check_hash(
|
super::check_hash(&self.path, self.size, self.hash.as_deref(), on_progress)
|
||||||
&self.path,
|
|
||||||
self.size,
|
|
||||||
self.hash.as_deref(),
|
|
||||||
on_progress,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,16 @@ pub trait Client {
|
||||||
|
|
||||||
fn share_notify(&self, uri: &Uri, alias_id: &AliasID, share_id: &ShareID) -> crate::Result<()>;
|
fn share_notify(&self, uri: &Uri, alias_id: &AliasID, share_id: &ShareID) -> crate::Result<()>;
|
||||||
|
|
||||||
|
/// create a new file in a Sharry share
|
||||||
|
///
|
||||||
|
/// - try to use endpoint from `Uri::file_create`
|
||||||
|
/// - try to extract `FileID` from the response
|
||||||
|
/// - return the new `FileID`
|
||||||
|
///
|
||||||
|
/// # Errors from
|
||||||
|
///
|
||||||
|
/// - request to endpoint
|
||||||
|
/// - parsing the response
|
||||||
fn file_create(
|
fn file_create(
|
||||||
&self,
|
&self,
|
||||||
uri: &Uri,
|
uri: &Uri,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue