Compare commits
2 commits
e98001f4a4
...
e908c09beb
| Author | SHA1 | Date | |
|---|---|---|---|
| e908c09beb | |||
| 3dc39edcab |
5 changed files with 71 additions and 83 deletions
31
.vscode/settings.json
vendored
31
.vscode/settings.json
vendored
|
|
@ -12,6 +12,37 @@
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"rust-analyzer.imports.prefix": "plain",
|
"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
|
// // 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
|
// // "can't find crate for `test`" when the default compilation target is a no_std target
|
||||||
// "rust-analyzer.checkOnSave.allTargets": false,
|
// "rust-analyzer.checkOnSave.allTargets": false,
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,8 @@ enum FileState {
|
||||||
impl FileState {
|
impl FileState {
|
||||||
fn file_name(&self) -> &str {
|
fn file_name(&self) -> &str {
|
||||||
match self {
|
match self {
|
||||||
FileState::C(checked) => checked.name(),
|
FileState::C(checked) => checked.get_name(),
|
||||||
FileState::U(uploading) => uploading.name(),
|
FileState::U(uploading) => uploading.get_name(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -133,7 +133,7 @@ impl AppState {
|
||||||
// Initialize or fetch the existing ProgressBar in one call:
|
// Initialize or fetch the existing ProgressBar in one call:
|
||||||
let bar = &*self.progress.get_or_insert_with(|| {
|
let bar = &*self.progress.get_or_insert_with(|| {
|
||||||
// Create a new bar with style
|
// Create a new bar with style
|
||||||
let bar = ProgressBar::new(uploading.size())
|
let bar = ProgressBar::new(uploading.get_size())
|
||||||
.with_style(
|
.with_style(
|
||||||
ProgressStyle::with_template(&format!(
|
ProgressStyle::with_template(&format!(
|
||||||
concat!(
|
concat!(
|
||||||
|
|
@ -145,8 +145,8 @@ impl AppState {
|
||||||
))
|
))
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
)
|
)
|
||||||
.with_message(uploading.name().to_owned())
|
.with_message(uploading.get_name().to_owned())
|
||||||
.with_position(uploading.offset());
|
.with_position(uploading.get_offset());
|
||||||
|
|
||||||
bar.enable_steady_tick(Duration::from_millis(100));
|
bar.enable_steady_tick(Duration::from_millis(100));
|
||||||
bar
|
bar
|
||||||
|
|
@ -154,7 +154,7 @@ impl AppState {
|
||||||
|
|
||||||
match uploading.upload_chunk(http, &self.alias, chunk_size) {
|
match uploading.upload_chunk(http, &self.alias, chunk_size) {
|
||||||
ChunkState::Ok(upl) => {
|
ChunkState::Ok(upl) => {
|
||||||
bar.set_position(upl.offset());
|
bar.set_position(upl.get_offset());
|
||||||
self.files.push_front(FileState::U(upl));
|
self.files.push_front(FileState::U(upl));
|
||||||
Ok(Some(()))
|
Ok(Some(()))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ use std::{
|
||||||
|
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use ureq::http::StatusCode;
|
use ureq::http::{HeaderValue, StatusCode};
|
||||||
|
|
||||||
use super::{Alias, FileUploading, Share, SharryAlias, SharryFile};
|
use super::{Alias, FileUploading, Share, SharryAlias, SharryFile};
|
||||||
|
|
||||||
|
|
@ -36,14 +36,14 @@ impl FileChecked {
|
||||||
alias: &Alias,
|
alias: &Alias,
|
||||||
share: &Share,
|
share: &Share,
|
||||||
) -> io::Result<FileUploading> {
|
) -> io::Result<FileUploading> {
|
||||||
let size: usize = self.size();
|
let size = self.get_size();
|
||||||
|
|
||||||
let res = {
|
let res = {
|
||||||
let endpoint = alias.get_endpoint(format!("alias/upload/{}/files/tus", share.id));
|
let endpoint = alias.get_endpoint(format!("alias/upload/{}/files/tus", share.id));
|
||||||
|
|
||||||
(http.post(endpoint))
|
(http.post(endpoint))
|
||||||
.sharry_header(alias)
|
.sharry_header(alias)
|
||||||
.header("Sharry-File-Name", self.name())
|
.header("Sharry-File-Name", self.get_name())
|
||||||
.header("Upload-Length", size)
|
.header("Upload-Length", size)
|
||||||
.send_empty()
|
.send_empty()
|
||||||
.map_err(ureq::Error::into_io)?
|
.map_err(ureq::Error::into_io)?
|
||||||
|
|
@ -68,25 +68,12 @@ impl FileChecked {
|
||||||
impl<'t> SharryFile<'t> for FileChecked {
|
impl<'t> SharryFile<'t> for FileChecked {
|
||||||
/// get a reference to the file's name
|
/// get a reference to the file's name
|
||||||
///
|
///
|
||||||
/// Uses SharryFile::extract_file_name, which may **panic**!
|
/// Uses `SharryFile::extract_file_name`, which may **panic**!
|
||||||
fn name(&'t self) -> &'t str {
|
fn get_name(&'t self) -> &'t str {
|
||||||
<Self as SharryFile>::extract_file_name(&self.path)
|
<Self as SharryFile>::extract_file_name(&self.path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn offset<T>(&self) -> T
|
fn get_size(&self) -> u64 {
|
||||||
where
|
fs::metadata(&self.path).unwrap().len()
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,50 +1,22 @@
|
||||||
use std::{
|
use std::{
|
||||||
ffi::OsStr,
|
ffi::OsStr,
|
||||||
fmt::{Debug, Display},
|
fmt::{Debug, Display},
|
||||||
path::{Path, PathBuf},
|
path::Path,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait SharryFile<'t> {
|
pub trait SharryFile<'t> {
|
||||||
/// get a reference to the filename from a PathBuf reference
|
/// extract the filename part of a `Path` reference
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Expects `Path::file_name` and `ffi::OsStr::to_str` to succeed on the contained path.
|
/// Expects `path::Path::file_name` and `ffi::OsStr::to_str` to succeed on the given path
|
||||||
fn extract_file_name(p: &'t PathBuf) -> &'t str {
|
fn extract_file_name(p: &'t Path) -> &'t str {
|
||||||
p.file_name()
|
p.file_name()
|
||||||
.and_then(OsStr::to_str)
|
.and_then(OsStr::to_str)
|
||||||
.expect("bad file name")
|
.expect("bad file name")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_usize<T>(val: usize) -> T
|
fn get_name(&'t self) -> &'t str;
|
||||||
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
|
fn get_size(&self) -> u64;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,9 @@ use super::{Alias, SharryAlias, SharryFile};
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub struct FileUploading {
|
pub struct FileUploading {
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
size: usize,
|
size: u64,
|
||||||
uri: String,
|
uri: String,
|
||||||
offset: usize,
|
offset: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -46,7 +46,7 @@ impl std::fmt::Display for FileUploading {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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 {
|
Self {
|
||||||
path,
|
path,
|
||||||
size,
|
size,
|
||||||
|
|
@ -55,11 +55,13 @@ impl FileUploading {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_chunk(&self, chunk_size: usize) -> io::Result<Vec<u8>> {
|
pub fn get_offset(&self) -> u64 {
|
||||||
let offset = u64::try_from(self.offset).map_err(io::Error::other)?;
|
self.offset
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_chunk(&self, chunk_size: usize) -> io::Result<Vec<u8>> {
|
||||||
let mut f = fs::File::open(&self.path)?;
|
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 mut bytes = vec![0; chunk_size];
|
||||||
let read_len = f.read(&mut bytes)?;
|
let read_len = f.read(&mut bytes)?;
|
||||||
|
|
@ -93,12 +95,20 @@ impl FileUploading {
|
||||||
|
|
||||||
let Some(Ok(Ok(res_offset))) = (res.headers().get("Upload-Offset"))
|
let Some(Ok(Ok(res_offset))) = (res.headers().get("Upload-Offset"))
|
||||||
.map(HeaderValue::to_str)
|
.map(HeaderValue::to_str)
|
||||||
.map(|v| v.map(str::parse::<usize>))
|
.map(|v| v.map(str::parse::<u64>))
|
||||||
else {
|
else {
|
||||||
return ChunkState::Err(self, UploadError::ResponseOffset);
|
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);
|
return ChunkState::Err(self, UploadError::ResponseOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -113,23 +123,11 @@ impl FileUploading {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'t> SharryFile<'t> for 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)
|
<Self as SharryFile>::extract_file_name(&self.path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn offset<T>(&self) -> T
|
fn get_size(&self) -> u64 {
|
||||||
where
|
self.size
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue