implement SharryFile trait
This commit is contained in:
parent
39560eeeed
commit
e98001f4a4
6 changed files with 111 additions and 42 deletions
|
|
@ -13,7 +13,7 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use super::{
|
||||
cli::Cli,
|
||||
sharry::{Alias, ChunkState, FileChecked, FileUploading, Share, UploadError},
|
||||
sharry::{Alias, ChunkState, FileChecked, FileUploading, Share, SharryFile, UploadError},
|
||||
};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
|
|
@ -37,8 +37,8 @@ enum FileState {
|
|||
impl FileState {
|
||||
fn file_name(&self) -> &str {
|
||||
match self {
|
||||
FileState::C(checked) => checked.file_name(),
|
||||
FileState::U(uploading) => uploading.file_name(),
|
||||
FileState::C(checked) => checked.name(),
|
||||
FileState::U(uploading) => uploading.name(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -145,7 +145,7 @@ impl AppState {
|
|||
))
|
||||
.unwrap(),
|
||||
)
|
||||
.with_message(uploading.file_name().to_owned())
|
||||
.with_message(uploading.name().to_owned())
|
||||
.with_position(uploading.offset());
|
||||
|
||||
bar.enable_steady_tick(Duration::from_millis(100));
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use log::debug;
|
|||
use serde::{Deserialize, Serialize};
|
||||
use ureq::http::StatusCode;
|
||||
|
||||
use super::{Alias, FileUploading, Share, SharryAlias};
|
||||
use super::{Alias, FileUploading, Share, SharryAlias, SharryFile};
|
||||
|
||||
#[derive(Debug, Clone, Hash, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct FileChecked {
|
||||
|
|
@ -30,30 +30,23 @@ impl FileChecked {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn file_name(&self) -> &str {
|
||||
self.path
|
||||
.file_name()
|
||||
.and_then(OsStr::to_str)
|
||||
.expect("bad file name")
|
||||
}
|
||||
|
||||
pub fn start_upload(
|
||||
self,
|
||||
http: &ureq::Agent,
|
||||
alias: &Alias,
|
||||
share: &Share,
|
||||
) -> io::Result<FileUploading> {
|
||||
let size = usize::try_from(fs::metadata(&self.path)?.len()).map_err(io::Error::other)?;
|
||||
let size: usize = self.size();
|
||||
|
||||
let res = {
|
||||
let endpoint = alias.get_endpoint(format!("alias/upload/{}/files/tus", share.id));
|
||||
|
||||
(http.post(endpoint))
|
||||
.sharry_header(alias)
|
||||
.header("Sharry-File-Name", self.file_name())
|
||||
.header("Sharry-File-Name", self.name())
|
||||
.header("Upload-Length", size)
|
||||
.send_empty()
|
||||
.map_err(io::Error::other)?
|
||||
.map_err(ureq::Error::into_io)?
|
||||
};
|
||||
|
||||
if res.status() != StatusCode::CREATED {
|
||||
|
|
@ -71,3 +64,29 @@ impl FileChecked {
|
|||
Ok(FileUploading::new(self.path, size, location))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'t> SharryFile<'t> for FileChecked {
|
||||
/// get a reference to the file's name
|
||||
///
|
||||
/// Uses SharryFile::extract_file_name, which may **panic**!
|
||||
fn name(&'t self) -> &'t str {
|
||||
<Self as SharryFile>::extract_file_name(&self.path)
|
||||
}
|
||||
|
||||
fn offset<T>(&self) -> T
|
||||
where
|
||||
T: TryFrom<usize>,
|
||||
<T as TryFrom<usize>>::Error: std::fmt::Debug + std::fmt::Display,
|
||||
{
|
||||
<Self as SharryFile>::from_usize(0)
|
||||
}
|
||||
|
||||
fn size<T>(&self) -> T
|
||||
where
|
||||
T: TryFrom<usize>,
|
||||
<T as TryFrom<usize>>::Error: std::fmt::Debug + std::fmt::Display,
|
||||
{
|
||||
let val = <Self as SharryFile>::to_usize(fs::metadata(&self.path).unwrap().len());
|
||||
<Self as SharryFile>::from_usize(val)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
50
src/sharry/file/filetrait.rs
Normal file
50
src/sharry/file/filetrait.rs
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
use std::{
|
||||
ffi::OsStr,
|
||||
fmt::{Debug, Display},
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
pub trait SharryFile<'t> {
|
||||
/// get a reference to the filename from a PathBuf reference
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Expects `Path::file_name` and `ffi::OsStr::to_str` to succeed on the contained path.
|
||||
fn extract_file_name(p: &'t PathBuf) -> &'t str {
|
||||
p.file_name()
|
||||
.and_then(OsStr::to_str)
|
||||
.expect("bad file name")
|
||||
}
|
||||
|
||||
fn from_usize<T>(val: usize) -> T
|
||||
where
|
||||
T: TryFrom<usize>,
|
||||
<T as TryFrom<usize>>::Error: Debug + Display,
|
||||
{
|
||||
val.try_into()
|
||||
.inspect_err(|e| panic!("usize did not fit into other type: {e}"))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn to_usize<T>(val: T) -> usize
|
||||
where
|
||||
T: TryInto<usize>,
|
||||
<T as TryInto<usize>>::Error: Debug + Display,
|
||||
{
|
||||
val.try_into()
|
||||
.inspect_err(|e| panic!("usize did not fit into other type: {e}"))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn name(&'t self) -> &'t str;
|
||||
|
||||
fn offset<T>(&self) -> T
|
||||
where
|
||||
T: TryFrom<usize>,
|
||||
<T as TryFrom<usize>>::Error: Debug + Display;
|
||||
|
||||
fn size<T>(&self) -> T
|
||||
where
|
||||
T: TryFrom<usize>,
|
||||
<T as TryFrom<usize>>::Error: Debug + Display;
|
||||
}
|
||||
|
|
@ -1,7 +1,9 @@
|
|||
mod checked;
|
||||
mod filetrait;
|
||||
mod uploading;
|
||||
|
||||
pub use checked::FileChecked;
|
||||
pub use filetrait::SharryFile;
|
||||
pub use uploading::{ChunkState, FileUploading, UploadError};
|
||||
|
||||
use super::{Alias, Share, alias::SharryAlias};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
use std::{
|
||||
ffi::OsStr,
|
||||
fmt::{Debug, Display},
|
||||
fs,
|
||||
io::{self, Read, Seek, SeekFrom},
|
||||
path::PathBuf,
|
||||
|
|
@ -10,7 +9,7 @@ use log::debug;
|
|||
use serde::{Deserialize, Serialize};
|
||||
use ureq::http::{HeaderValue, StatusCode};
|
||||
|
||||
use super::{Alias, SharryAlias};
|
||||
use super::{Alias, SharryAlias, SharryFile};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct FileUploading {
|
||||
|
|
@ -34,7 +33,7 @@ pub enum ChunkState {
|
|||
Finished(PathBuf),
|
||||
}
|
||||
|
||||
impl Display for FileUploading {
|
||||
impl std::fmt::Display for FileUploading {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
|
|
@ -69,29 +68,6 @@ impl FileUploading {
|
|||
Ok(bytes)
|
||||
}
|
||||
|
||||
pub fn file_name(&self) -> &str {
|
||||
self.path
|
||||
.file_name()
|
||||
.and_then(OsStr::to_str)
|
||||
.expect("bad file name")
|
||||
}
|
||||
|
||||
pub fn offset<T>(&self) -> T
|
||||
where
|
||||
T: TryFrom<usize>,
|
||||
<T as TryFrom<usize>>::Error: Debug,
|
||||
{
|
||||
self.offset.try_into().unwrap()
|
||||
}
|
||||
|
||||
pub fn size<T>(&self) -> T
|
||||
where
|
||||
T: TryFrom<usize>,
|
||||
<T as TryFrom<usize>>::Error: Debug,
|
||||
{
|
||||
self.size.try_into().unwrap()
|
||||
}
|
||||
|
||||
pub fn upload_chunk(
|
||||
mut self,
|
||||
http: &ureq::Agent,
|
||||
|
|
@ -135,3 +111,25 @@ impl FileUploading {
|
|||
ChunkState::Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'t> SharryFile<'t> for FileUploading {
|
||||
fn name(&'t self) -> &'t str {
|
||||
<Self as SharryFile>::extract_file_name(&self.path)
|
||||
}
|
||||
|
||||
fn offset<T>(&self) -> T
|
||||
where
|
||||
T: TryFrom<usize>,
|
||||
<T as TryFrom<usize>>::Error: std::fmt::Debug + std::fmt::Display,
|
||||
{
|
||||
<Self as SharryFile>::from_usize(self.offset)
|
||||
}
|
||||
|
||||
fn size<T>(&self) -> T
|
||||
where
|
||||
T: TryFrom<usize>,
|
||||
<T as TryFrom<usize>>::Error: std::fmt::Debug + std::fmt::Display,
|
||||
{
|
||||
<Self as SharryFile>::from_usize(self.size)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,5 +7,5 @@ mod share;
|
|||
|
||||
pub use alias::Alias;
|
||||
pub use api::{NewShareRequest, Uri};
|
||||
pub use file::{ChunkState, FileChecked, FileUploading, UploadError};
|
||||
pub use file::{ChunkState, FileChecked, FileUploading, SharryFile, UploadError};
|
||||
pub use share::Share;
|
||||
|
|
|
|||
Loading…
Reference in a new issue