Compare commits
No commits in common. "7bbb2bbc19d453c447f5f88105a9276ace9c9f1f" and "b3bccbbf65a59a2189ce0d36a64576a88db0088a" have entirely different histories.
7bbb2bbc19
...
b3bccbbf65
7 changed files with 30 additions and 135 deletions
|
|
@ -13,10 +13,7 @@
|
|||
"configureZshAsDefaultShell": "true"
|
||||
},
|
||||
"ghcr.io/devcontainers/features/rust:1": {
|
||||
"targets": "x86_64-unknown-linux-gnu,x86_64-unknown-linux-musl"
|
||||
},
|
||||
"ghcr.io/lee-orr/rusty-dev-containers/cargo-binstall:0": {
|
||||
"packages": "cargo-llvm-cov"
|
||||
"targets": "x86_64-unknown-linux-musl"
|
||||
},
|
||||
"ghcr.io/devcontainers-contrib/features/apt-get-packages:1": {
|
||||
"packages": "git-flow, musl-tools"
|
||||
|
|
@ -36,7 +33,7 @@
|
|||
// "forwardPorts": [],
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
// "postCreateCommand": "rustup target install x86_64-unknown-linux-musl | :",
|
||||
"postCreateCommand": "rustup target install x86_64-unknown-linux-musl | :",
|
||||
|
||||
// Configure tool-specific properties.
|
||||
"customizations": {
|
||||
|
|
@ -46,8 +43,7 @@
|
|||
},
|
||||
"extensions": [
|
||||
"mhutchie.git-graph",
|
||||
"Gruntfuggly.todo-tree",
|
||||
"ryanluker.vscode-coverage-gutters"
|
||||
"Gruntfuggly.todo-tree"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
|
|
|||
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -1,7 +1,3 @@
|
|||
# code coverage reports
|
||||
coverage/
|
||||
|
||||
|
||||
# https://github.com/github/gitignore/raw/refs/heads/main/Rust.gitignore
|
||||
|
||||
# Generated by Cargo
|
||||
|
|
|
|||
54
.vscode/tasks.json
vendored
54
.vscode/tasks.json
vendored
|
|
@ -5,6 +5,9 @@
|
|||
"label": "Build Project",
|
||||
"type": "cargo",
|
||||
"command": "build",
|
||||
// "presentation": {
|
||||
// "reveal": "silent"
|
||||
// },
|
||||
"problemMatcher": "$rustc",
|
||||
"group": "build"
|
||||
},
|
||||
|
|
@ -70,62 +73,13 @@
|
|||
// "problemMatcher": "$rustc",
|
||||
// "group": "test"
|
||||
// },
|
||||
{
|
||||
"label": "Test Coverage",
|
||||
"hide": true,
|
||||
"type": "cargo",
|
||||
"command": "llvm-cov",
|
||||
"args": [],
|
||||
"problemMatcher": "$rustc",
|
||||
"group": "test",
|
||||
},
|
||||
{
|
||||
"label": "Report Coverage (html)",
|
||||
"hide": true,
|
||||
"type": "cargo",
|
||||
"command": "llvm-cov",
|
||||
"args": [
|
||||
"report",
|
||||
"--html",
|
||||
"--output-dir" ,
|
||||
"coverage",
|
||||
],
|
||||
"problemMatcher": "$rustc",
|
||||
"group": "test"
|
||||
},
|
||||
{
|
||||
"label": "Report Coverage (lcov)",
|
||||
"hide": true,
|
||||
"type": "cargo",
|
||||
"command": "llvm-cov",
|
||||
"args": [
|
||||
"report",
|
||||
"--lcov",
|
||||
"--output-path" ,
|
||||
"coverage/lcov.info",
|
||||
],
|
||||
"problemMatcher": "$rustc",
|
||||
"group": "test"
|
||||
},
|
||||
{
|
||||
"label": "Run Coverage",
|
||||
"type": "shell",
|
||||
"dependsOn": [
|
||||
"Test Coverage",
|
||||
"Report Coverage (html)",
|
||||
"Report Coverage (lcov)",
|
||||
],
|
||||
"dependsOrder": "sequence",
|
||||
"group": "test"
|
||||
},
|
||||
{
|
||||
"label": "Run All Tests",
|
||||
"type": "shell",
|
||||
"command": "echo All Tests successful!",
|
||||
"dependsOn": [
|
||||
"Run Unit Tests",
|
||||
// "Run Integration Tests",
|
||||
"Run Coverage",
|
||||
// "Run Integration Tests"
|
||||
],
|
||||
"dependsOrder": "sequence",
|
||||
"group": "test"
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ impl CacheFile {
|
|||
.take()
|
||||
.expect("abort_upload called while not uploading");
|
||||
|
||||
self.files.push_front(upl.stop());
|
||||
self.files.push_front(upl.into());
|
||||
}
|
||||
|
||||
pub fn share_notify(&self, client: &impl Client) -> crate::Result<()> {
|
||||
|
|
|
|||
|
|
@ -115,27 +115,20 @@ impl FileTrait for Checked {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use tempfile::{NamedTempFile, TempDir};
|
||||
use tempfile::TempDir;
|
||||
|
||||
use crate::test_util::{
|
||||
MockClient, check_trait, create_file,
|
||||
MockClient, create_file,
|
||||
data::{HASHES_STD_GOOD, cases, data},
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
fn create_checked(content: &[u8]) -> (Checked, NamedTempFile) {
|
||||
let file = create_file(content);
|
||||
let chk = Checked::new(file.path()).expect("creating `Checked` should succeed");
|
||||
|
||||
// return both, so the `NamedTempFile` is not auto-deleted here
|
||||
(chk, file)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn new_on_existing_file_works() {
|
||||
for (content, size) in cases() {
|
||||
let (chk, file) = create_checked(content);
|
||||
let file = create_file(content);
|
||||
let chk = Checked::new(file.path()).expect("creating `Checked` should succeed");
|
||||
|
||||
let path = file
|
||||
.path()
|
||||
|
|
@ -152,19 +145,6 @@ mod tests {
|
|||
file.path().file_name().expect("`file_name` should succeed")
|
||||
);
|
||||
assert_eq!(chk.get_size(), size);
|
||||
|
||||
check_trait(
|
||||
chk.as_ref(),
|
||||
path.as_os_str().as_encoded_bytes(),
|
||||
"AsRef<u8>",
|
||||
"Checked",
|
||||
);
|
||||
|
||||
// new_direct
|
||||
let chk = Checked::new_direct(chk.path, chk.size, chk.hash);
|
||||
assert_eq!(chk.path, path);
|
||||
assert_eq!(chk.size, size);
|
||||
assert!(chk.hash.is_none());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -199,7 +179,8 @@ mod tests {
|
|||
#[test]
|
||||
fn hashing_works() {
|
||||
for (content, hash) in data().zip(HASHES_STD_GOOD) {
|
||||
let (mut chk, _file) = create_checked(content);
|
||||
let file = create_file(content);
|
||||
let mut chk = Checked::new(file.path()).expect("creating `Checked` should succeed");
|
||||
|
||||
chk.hash(drop).expect("`hash` should succeed");
|
||||
// `FileTrait`
|
||||
|
|
@ -212,10 +193,10 @@ mod tests {
|
|||
#[test]
|
||||
fn hashing_again_errors() {
|
||||
for content in data() {
|
||||
let (mut chk, _file) = create_checked(content);
|
||||
let file = create_file(content);
|
||||
let mut chk = Checked::new(file.path()).expect("creating `Checked` should succeed");
|
||||
|
||||
// fake hash
|
||||
chk.hash = Some(String::default());
|
||||
chk.hash(drop).expect("`hash` should succeed");
|
||||
let err = chk.hash(drop).expect_err("`hash` twice should fail");
|
||||
|
||||
assert!(err.is_mismatch("unhashed file", chk.path.display().to_string()));
|
||||
|
|
@ -228,7 +209,8 @@ mod tests {
|
|||
let share_id = client.add_share();
|
||||
|
||||
for content in data() {
|
||||
let (chk, _file) = create_checked(content);
|
||||
let file = create_file(content);
|
||||
let chk = Checked::new(file.path()).expect("creating `Checked` should succeed");
|
||||
|
||||
assert!(
|
||||
chk.start_upload(
|
||||
|
|
|
|||
|
|
@ -1,19 +1,14 @@
|
|||
use std::{any, fmt};
|
||||
use std::fmt;
|
||||
|
||||
use crate::sharry;
|
||||
|
||||
/// Chunk of binary data belonging to a currently uploading file
|
||||
pub struct Chunk<'t> {
|
||||
/// id of the associated file
|
||||
file_id: sharry::FileID,
|
||||
/// offset of this chunk in bytes
|
||||
offset: u64,
|
||||
/// data inside this chunk
|
||||
data: &'t [u8],
|
||||
}
|
||||
|
||||
impl fmt::Debug for Chunk<'_> {
|
||||
// chunks are 1 MiB or more, we shouldn't print that
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("Chunk")
|
||||
.field("file_id", &self.file_id)
|
||||
|
|
@ -23,22 +18,6 @@ impl fmt::Debug for Chunk<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
/// convert usize into other type
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// - if the given value does not fit into the target type
|
||||
fn from_usize_or_panic<I>(value: usize) -> I
|
||||
where
|
||||
I: TryFrom<usize>,
|
||||
I::Error: std::error::Error,
|
||||
{
|
||||
value.try_into().unwrap_or_else(|e| {
|
||||
let target_type = any::type_name::<I>();
|
||||
panic!("usize={value:?} did not fit into {target_type:?}: {e}")
|
||||
})
|
||||
}
|
||||
|
||||
impl<'t> Chunk<'t> {
|
||||
pub(super) fn new_direct(file_id: sharry::FileID, offset: u64, data: &'t [u8]) -> Self {
|
||||
Self {
|
||||
|
|
@ -65,10 +44,12 @@ impl<'t> Chunk<'t> {
|
|||
|
||||
/// get the chunk's length
|
||||
pub fn get_length(&self) -> u64 {
|
||||
// BOOKMARK this might **panic** on (hypothetical) platforms where `usize` has more than 64 bit.
|
||||
let len = self.data.len();
|
||||
|
||||
// BOOKMARK this might **panic** on platforms where `usize` has more than 64 bit.
|
||||
// Also, you've allocated more than 2 EiB ... in ONE chunk.
|
||||
// Whoa! Maybe just chill?
|
||||
from_usize_or_panic(self.data.len())
|
||||
u64::try_from(len).unwrap_or_else(|e| panic!("usize={len} did not fit into u64: {e}"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -104,17 +85,4 @@ mod tests {
|
|||
assert_eq!(chunk.get_length(), len);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "did not fit into \"u32\"")]
|
||||
fn test_usize_overflow_panics() {
|
||||
// works
|
||||
assert_eq!(from_usize_or_panic::<u64>(usize::MAX), u64::MAX);
|
||||
assert_eq!(from_usize_or_panic::<u32>(u32::MAX as usize), u32::MAX);
|
||||
assert_eq!(from_usize_or_panic::<u16>(u16::MAX as usize), u16::MAX);
|
||||
assert_eq!(from_usize_or_panic::<u8>(u8::MAX as usize), u8::MAX);
|
||||
|
||||
// panics
|
||||
from_usize_or_panic::<u32>(usize::MAX);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,12 @@ pub struct Uploading {
|
|||
offset: u64,
|
||||
}
|
||||
|
||||
impl From<Uploading> for Checked {
|
||||
fn from(value: Uploading) -> Self {
|
||||
Self::new_direct(value.path, value.size, value.hash)
|
||||
}
|
||||
}
|
||||
|
||||
impl Uploading {
|
||||
pub(super) fn new_direct(
|
||||
path: PathBuf,
|
||||
|
|
@ -112,13 +118,6 @@ impl Uploading {
|
|||
Err(self.path)
|
||||
}
|
||||
}
|
||||
|
||||
/// stop uploading this file
|
||||
///
|
||||
/// - consume self, returning as a `file::Checked`
|
||||
pub fn stop(self) -> Checked {
|
||||
Checked::new_direct(self.path, self.size, self.hash)
|
||||
}
|
||||
}
|
||||
|
||||
impl FileTrait for Uploading {
|
||||
|
|
|
|||
Loading…
Reference in a new issue