Compare commits

...

2 commits

5 changed files with 71 additions and 83 deletions

31
.vscode/settings.json vendored
View file

@ -12,6 +12,37 @@
},
},
"rust-analyzer.imports.prefix": "plain",
"todo-tree.general.tags": [
"BUG",
"HACK",
"FIXME",
"TODO",
"XXX",
"[ ]",
"[x]",
"BOOKMARK"
],
"todo-tree.highlights.backgroundColourScheme": [
"red",
"orange",
"yellow",
"green",
"blue",
"indigo",
"violet",
"yellow"
],
"todo-tree.highlights.foregroundColourScheme": [
"white",
"black",
"black",
"white",
"white",
"white",
"black",
"black"
],
"todo-tree.highlights.useColourScheme": true,
// // override the default setting (`cargo check --all-targets`) which produces the following error
// // "can't find crate for `test`" when the default compilation target is a no_std target
// "rust-analyzer.checkOnSave.allTargets": false,

View file

@ -37,8 +37,8 @@ enum FileState {
impl FileState {
fn file_name(&self) -> &str {
match self {
FileState::C(checked) => checked.name(),
FileState::U(uploading) => uploading.name(),
FileState::C(checked) => checked.get_name(),
FileState::U(uploading) => uploading.get_name(),
}
}
@ -133,7 +133,7 @@ impl AppState {
// Initialize or fetch the existing ProgressBar in one call:
let bar = &*self.progress.get_or_insert_with(|| {
// Create a new bar with style
let bar = ProgressBar::new(uploading.size())
let bar = ProgressBar::new(uploading.get_size())
.with_style(
ProgressStyle::with_template(&format!(
concat!(
@ -145,8 +145,8 @@ impl AppState {
))
.unwrap(),
)
.with_message(uploading.name().to_owned())
.with_position(uploading.offset());
.with_message(uploading.get_name().to_owned())
.with_position(uploading.get_offset());
bar.enable_steady_tick(Duration::from_millis(100));
bar
@ -154,7 +154,7 @@ impl AppState {
match uploading.upload_chunk(http, &self.alias, chunk_size) {
ChunkState::Ok(upl) => {
bar.set_position(upl.offset());
bar.set_position(upl.get_offset());
self.files.push_front(FileState::U(upl));
Ok(Some(()))
}

View file

@ -6,7 +6,7 @@ use std::{
use log::debug;
use serde::{Deserialize, Serialize};
use ureq::http::StatusCode;
use ureq::http::{HeaderValue, StatusCode};
use super::{Alias, FileUploading, Share, SharryAlias, SharryFile};
@ -36,14 +36,14 @@ impl FileChecked {
alias: &Alias,
share: &Share,
) -> io::Result<FileUploading> {
let size: usize = self.size();
let size = self.get_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.name())
.header("Sharry-File-Name", self.get_name())
.header("Upload-Length", size)
.send_empty()
.map_err(ureq::Error::into_io)?
@ -68,25 +68,12 @@ impl FileChecked {
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 {
/// Uses `SharryFile::extract_file_name`, which may **panic**!
fn get_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)
fn get_size(&self) -> u64 {
fs::metadata(&self.path).unwrap().len()
}
}

View file

@ -1,50 +1,22 @@
use std::{
ffi::OsStr,
fmt::{Debug, Display},
path::{Path, PathBuf},
path::Path,
};
pub trait SharryFile<'t> {
/// get a reference to the filename from a PathBuf reference
/// extract the filename part of a `Path` 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 {
/// Expects `path::Path::file_name` and `ffi::OsStr::to_str` to succeed on the given path
fn extract_file_name(p: &'t Path) -> &'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 get_name(&'t self) -> &'t str;
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;
fn get_size(&self) -> u64;
}

View file

@ -14,9 +14,9 @@ use super::{Alias, SharryAlias, SharryFile};
#[derive(Serialize, Deserialize, Debug)]
pub struct FileUploading {
path: PathBuf,
size: usize,
size: u64,
uri: String,
offset: usize,
offset: u64,
}
#[derive(Debug)]
@ -46,7 +46,7 @@ impl std::fmt::Display for FileUploading {
}
impl FileUploading {
pub(super) fn new(path: PathBuf, size: usize, uri: String) -> Self {
pub(super) fn new(path: PathBuf, size: u64, uri: String) -> Self {
Self {
path,
size,
@ -55,11 +55,13 @@ impl FileUploading {
}
}
fn read_chunk(&self, chunk_size: usize) -> io::Result<Vec<u8>> {
let offset = u64::try_from(self.offset).map_err(io::Error::other)?;
pub fn get_offset(&self) -> u64 {
self.offset
}
fn read_chunk(&self, chunk_size: usize) -> io::Result<Vec<u8>> {
let mut f = fs::File::open(&self.path)?;
f.seek(SeekFrom::Start(offset))?;
f.seek(SeekFrom::Start(self.offset))?;
let mut bytes = vec![0; chunk_size];
let read_len = f.read(&mut bytes)?;
@ -93,12 +95,20 @@ impl FileUploading {
let Some(Ok(Ok(res_offset))) = (res.headers().get("Upload-Offset"))
.map(HeaderValue::to_str)
.map(|v| v.map(str::parse::<usize>))
.map(|v| v.map(str::parse::<u64>))
else {
return ChunkState::Err(self, UploadError::ResponseOffset);
};
if self.offset + chunk.len() != res_offset {
// convert chunk.len() into an `u64`
//
// BOOKMARK this might panic on platforms where `usize` > 64 bit.
// Also whoa, you've sent more than 2 EiB ... in ONE chunk.
// Maybe just chill?
let chunk_len = u64::try_from(chunk.len())
.unwrap_or_else(|e| panic!("usize={} did not fit into u64: {}", chunk.len(), e));
if self.offset + chunk_len != res_offset {
return ChunkState::Err(self, UploadError::ResponseOffset);
}
@ -113,23 +123,11 @@ impl FileUploading {
}
impl<'t> SharryFile<'t> for FileUploading {
fn name(&'t self) -> &'t str {
fn get_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)
fn get_size(&self) -> u64 {
self.size
}
}