Apply clippy suggestions
This commit is contained in:
parent
f0ca016f4a
commit
b62f3fd343
34 changed files with 126 additions and 119 deletions
|
@ -24,7 +24,7 @@ impl<'a> Delete<'a> {
|
|||
pub fn new(file: &'a RemoteFile, nonce: Option<Vec<u8>>) -> Self {
|
||||
Self {
|
||||
file,
|
||||
nonce: nonce.unwrap_or(Vec::new()),
|
||||
nonce: nonce.unwrap_or_default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ impl<'a> Delete<'a> {
|
|||
))?;
|
||||
|
||||
// Send the delete request
|
||||
self.request_delete(client, data).map_err(|err| err.into())
|
||||
self.request_delete(client, &data)
|
||||
}
|
||||
|
||||
/// Fetch the authentication nonce for the file from the remote server.
|
||||
|
@ -59,7 +59,7 @@ impl<'a> Delete<'a> {
|
|||
fn request_delete(
|
||||
&self,
|
||||
client: &Client,
|
||||
data: OwnedData<DeleteData>,
|
||||
data: &OwnedData<DeleteData>,
|
||||
) -> Result<(), Error> {
|
||||
// Get the delete URL, and send the request
|
||||
let url = UrlBuilder::api_delete(self.file);
|
||||
|
@ -77,13 +77,13 @@ impl<'a> Delete<'a> {
|
|||
/// The delete data object.
|
||||
/// This object is currently empty, as no additional data is sent to the
|
||||
/// server.
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(Debug, Serialize, Default)]
|
||||
pub struct DeleteData { }
|
||||
|
||||
impl DeleteData {
|
||||
/// Constructor.
|
||||
pub fn new() -> Self {
|
||||
DeleteData { }
|
||||
DeleteData::default()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ impl<'a> Download<'a> {
|
|||
pub fn invoke(
|
||||
mut self,
|
||||
client: &Client,
|
||||
reporter: Arc<Mutex<ProgressReporter>>,
|
||||
reporter: &Arc<Mutex<ProgressReporter>>,
|
||||
) -> Result<(), Error> {
|
||||
// Create a key set for the file
|
||||
let mut key = KeySet::from(self.file, self.password.as_ref());
|
||||
|
@ -101,7 +101,7 @@ impl<'a> Download<'a> {
|
|||
// Create the file reader for downloading
|
||||
let (reader, len) = self.create_file_reader(
|
||||
&key,
|
||||
metadata.nonce().to_vec(),
|
||||
metadata.nonce(),
|
||||
&client,
|
||||
)?;
|
||||
|
||||
|
@ -110,11 +110,11 @@ impl<'a> Download<'a> {
|
|||
out,
|
||||
len,
|
||||
&key,
|
||||
reporter.clone(),
|
||||
&reporter,
|
||||
).map_err(|err| Error::File(path_str.clone(), err))?;
|
||||
|
||||
// Download the file
|
||||
self.download(reader, writer, len, reporter)?;
|
||||
self.download(reader, writer, len, &reporter)?;
|
||||
|
||||
// TODO: return the file path
|
||||
// TODO: return the new remote state (does it still exist remote)
|
||||
|
@ -160,7 +160,7 @@ impl<'a> Download<'a> {
|
|||
fn create_file_reader(
|
||||
&self,
|
||||
key: &KeySet,
|
||||
meta_nonce: Vec<u8>,
|
||||
meta_nonce: &[u8],
|
||||
client: &Client,
|
||||
) -> Result<(Response, u64), DownloadError> {
|
||||
// Compute the cryptographic signature
|
||||
|
@ -177,7 +177,7 @@ impl<'a> Download<'a> {
|
|||
|
||||
// Ensure the response is succesful
|
||||
ensure_success(&response)
|
||||
.map_err(|err| DownloadError::Response(err))?;
|
||||
.map_err(DownloadError::Response)?;
|
||||
|
||||
// Get the content length
|
||||
// TODO: make sure there is enough disk space
|
||||
|
@ -196,7 +196,7 @@ impl<'a> Download<'a> {
|
|||
file: File,
|
||||
len: u64,
|
||||
key: &KeySet,
|
||||
reporter: Arc<Mutex<ProgressReporter>>,
|
||||
reporter: &Arc<Mutex<ProgressReporter>>,
|
||||
) -> Result<ProgressWriter<EncryptedFileWriter>, FileError> {
|
||||
// Build an encrypted writer
|
||||
let mut writer = ProgressWriter::new(
|
||||
|
@ -223,7 +223,7 @@ impl<'a> Download<'a> {
|
|||
mut reader: R,
|
||||
mut writer: ProgressWriter<EncryptedFileWriter>,
|
||||
len: u64,
|
||||
reporter: Arc<Mutex<ProgressReporter>>,
|
||||
reporter: &Arc<Mutex<ProgressReporter>>,
|
||||
) -> Result<(), DownloadError> {
|
||||
// Start the writer
|
||||
reporter.lock()
|
||||
|
|
|
@ -29,7 +29,7 @@ impl<'a> Info<'a> {
|
|||
pub fn new(file: &'a RemoteFile, nonce: Option<Vec<u8>>) -> Self {
|
||||
Self {
|
||||
file,
|
||||
nonce: nonce.unwrap_or(Vec::new()),
|
||||
nonce: nonce.unwrap_or_default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ impl<'a> Info<'a> {
|
|||
.map_err(|err| -> PrepareError { err.into() })?;
|
||||
|
||||
// Send the info request
|
||||
self.fetch_info(client, data).map_err(|err| err.into())
|
||||
self.fetch_info(client, &data)
|
||||
}
|
||||
|
||||
/// Fetch the authentication nonce for the file from the remote server.
|
||||
|
@ -62,7 +62,7 @@ impl<'a> Info<'a> {
|
|||
fn fetch_info(
|
||||
&self,
|
||||
client: &Client,
|
||||
data: OwnedData<InfoData>,
|
||||
data: &OwnedData<InfoData>,
|
||||
) -> Result<InfoResponse, Error> {
|
||||
// Get the info URL, and send the request
|
||||
let url = UrlBuilder::api_info(self.file);
|
||||
|
@ -87,13 +87,13 @@ impl<'a> Info<'a> {
|
|||
/// The info data object.
|
||||
/// This object is currently empty, as no additional data is sent to the
|
||||
/// server.
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(Debug, Serialize, Default)]
|
||||
pub struct InfoData { }
|
||||
|
||||
impl InfoData {
|
||||
/// Constructor.
|
||||
pub fn new() -> Self {
|
||||
InfoData { }
|
||||
InfoData::default()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -56,19 +56,19 @@ impl<'a> Metadata<'a> {
|
|||
}
|
||||
|
||||
// Make sure a password is given when it is required
|
||||
if !self.password.is_some() && exist_response.has_password() {
|
||||
if self.password.is_none() && exist_response.has_password() {
|
||||
return Err(Error::PasswordRequired);
|
||||
}
|
||||
}
|
||||
|
||||
// Create a key set for the file
|
||||
let mut key = KeySet::from(self.file, self.password.as_ref());
|
||||
let key = KeySet::from(self.file, self.password.as_ref());
|
||||
|
||||
// Fetch the authentication nonce
|
||||
let auth_nonce = self.fetch_auth_nonce(client)?;
|
||||
|
||||
// Fetch the metadata and the metadata nonce, return the result
|
||||
self.fetch_metadata(&client, &mut key, auth_nonce)
|
||||
self.fetch_metadata(&client, &key, &auth_nonce)
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ impl<'a> Metadata<'a> {
|
|||
&self,
|
||||
client: &Client,
|
||||
key: &KeySet,
|
||||
auth_nonce: Vec<u8>,
|
||||
auth_nonce: &[u8],
|
||||
) -> Result<MetadataResponse, MetaError> {
|
||||
// Compute the cryptographic signature for authentication
|
||||
let sig = signature_encoded(key.auth_key().unwrap(), &auth_nonce)
|
||||
|
@ -108,11 +108,11 @@ impl<'a> Metadata<'a> {
|
|||
|
||||
// Ensure the status code is successful
|
||||
ensure_success(&response)
|
||||
.map_err(|err| MetaError::NonceResponse(err))?;
|
||||
.map_err(MetaError::NonceResponse)?;
|
||||
|
||||
// Get the metadata nonce
|
||||
let nonce = header_nonce(&response)
|
||||
.map_err(|err| MetaError::Nonce(err))?;
|
||||
.map_err(MetaError::Nonce)?;
|
||||
|
||||
// Parse the metadata response
|
||||
MetadataResponse::from(
|
||||
|
|
|
@ -11,7 +11,7 @@ use file::remote_file::RemoteFile;
|
|||
|
||||
/// The default download count.
|
||||
pub const PARAMS_DEFAULT_DOWNLOAD: u8 = 1;
|
||||
pub const PARAMS_DEFAULT_DOWNLOAD_STR: &'static str = "1";
|
||||
pub const PARAMS_DEFAULT_DOWNLOAD_STR: &str = "1";
|
||||
|
||||
/// The minimum allowed number of downloads, enforced by the server.
|
||||
pub const PARAMS_DOWNLOAD_MIN: u8 = 1;
|
||||
|
@ -43,7 +43,7 @@ impl<'a> Params<'a> {
|
|||
Self {
|
||||
file,
|
||||
params,
|
||||
nonce: nonce.unwrap_or(Vec::new()),
|
||||
nonce: nonce.unwrap_or_default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,8 +61,7 @@ impl<'a> Params<'a> {
|
|||
.map_err(|err| -> PrepareError { err.into() })?;
|
||||
|
||||
// Send the request to change the parameters
|
||||
self.change_params(client, data)
|
||||
.map_err(|err| err.into())
|
||||
self.change_params(client, &data)
|
||||
}
|
||||
|
||||
/// Fetch the authentication nonce for the file from the remote server.
|
||||
|
@ -79,7 +78,7 @@ impl<'a> Params<'a> {
|
|||
fn change_params(
|
||||
&self,
|
||||
client: &Client,
|
||||
data: OwnedData<ParamsData>,
|
||||
data: &OwnedData<ParamsData>,
|
||||
) -> Result<(), Error> {
|
||||
// Get the params URL, and send the change
|
||||
let url = UrlBuilder::api_params(self.file);
|
||||
|
|
|
@ -33,7 +33,7 @@ impl<'a> Password<'a> {
|
|||
Self {
|
||||
file,
|
||||
password,
|
||||
nonce: nonce.unwrap_or(Vec::new()),
|
||||
nonce: nonce.unwrap_or_default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,8 +55,7 @@ impl<'a> Password<'a> {
|
|||
.map_err(|err| -> PrepareError { err.into() })?;
|
||||
|
||||
// Send the request to change the password
|
||||
self.change_password(client, data)
|
||||
.map_err(|err| err.into())
|
||||
self.change_password(client, &data)
|
||||
}
|
||||
|
||||
/// Fetch the authentication nonce for the file from the Send server.
|
||||
|
@ -73,7 +72,7 @@ impl<'a> Password<'a> {
|
|||
fn change_password(
|
||||
&self,
|
||||
client: &Client,
|
||||
data: OwnedData<PasswordData>,
|
||||
data: &OwnedData<PasswordData>,
|
||||
) -> Result<(), Error> {
|
||||
// Get the password URL, and send the change
|
||||
let url = UrlBuilder::api_password(self.file);
|
||||
|
|
|
@ -86,7 +86,7 @@ impl Upload {
|
|||
pub fn invoke(
|
||||
self,
|
||||
client: &Client,
|
||||
reporter: Arc<Mutex<ProgressReporter>>,
|
||||
reporter: &Arc<Mutex<ProgressReporter>>,
|
||||
) -> Result<RemoteFile, Error> {
|
||||
// Create file data, generate a key
|
||||
let file = FileData::from(&self.path)?;
|
||||
|
@ -101,7 +101,7 @@ impl Upload {
|
|||
let req = self.create_request(
|
||||
client,
|
||||
&key,
|
||||
metadata,
|
||||
&metadata,
|
||||
reader,
|
||||
);
|
||||
|
||||
|
@ -137,13 +137,13 @@ impl Upload {
|
|||
{
|
||||
// Determine what filename to use
|
||||
let name = self.name.clone()
|
||||
.unwrap_or(file.name().to_owned());
|
||||
.unwrap_or_else(|| file.name().to_owned());
|
||||
|
||||
// Construct the metadata
|
||||
let metadata = Metadata::from(
|
||||
key.iv(),
|
||||
name,
|
||||
file.mime().clone(),
|
||||
&file.mime(),
|
||||
).to_json().into_bytes();
|
||||
|
||||
// Encrypt the metadata
|
||||
|
@ -207,7 +207,7 @@ impl Upload {
|
|||
&self,
|
||||
client: &Client,
|
||||
key: &KeySet,
|
||||
metadata: Vec<u8>,
|
||||
metadata: &[u8],
|
||||
reader: EncryptedReader,
|
||||
) -> Request {
|
||||
// Get the reader length
|
||||
|
@ -250,7 +250,7 @@ impl Upload {
|
|||
|
||||
// Ensure the response is successful
|
||||
ensure_success(&response)
|
||||
.map_err(|err| UploadError::Response(err))?;
|
||||
.map_err(UploadError::Response)?;
|
||||
|
||||
// Try to get the nonce, don't error on failure
|
||||
let nonce = header_nonce(&response).ok();
|
||||
|
|
|
@ -5,7 +5,7 @@ use api::request::{ensure_success, ResponseError};
|
|||
use crypto::b64;
|
||||
|
||||
/// The name of the header the nonce is delivered in.
|
||||
const HEADER_NONCE: &'static str = "WWW-Authenticate";
|
||||
const HEADER_NONCE: &str = "WWW-Authenticate";
|
||||
|
||||
/// Do a new request, and extract the nonce from a header in the given
|
||||
/// response.
|
||||
|
@ -38,11 +38,10 @@ pub fn header_nonce(response: &Response)
|
|||
.and_then(|line| String::from_utf8(line.to_vec())
|
||||
.map_err(|_| NonceError::MalformedNonce)
|
||||
)?
|
||||
.split_terminator(" ")
|
||||
.skip(1)
|
||||
.next()
|
||||
.split_terminator(' ')
|
||||
.nth(2)
|
||||
.ok_or(NonceError::MalformedNonce)?
|
||||
).map_err(|_| NonceError::MalformedNonce.into())
|
||||
).map_err(|_| NonceError::MalformedNonce)
|
||||
}
|
||||
|
||||
#[derive(Fail, Debug)]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use reqwest::StatusCode;
|
||||
|
||||
/// The Send host to use by default.
|
||||
pub const SEND_DEFAULT_HOST: &'static str = "https://send.firefox.com/";
|
||||
pub const SEND_DEFAULT_HOST: &str = "https://send.firefox.com/";
|
||||
|
||||
/// The default time after which uploaded files expire after, in seconds.
|
||||
pub const SEND_DEFAULT_EXPIRE_TIME: i64 = 24 * 60 * 60;
|
||||
|
@ -13,7 +13,7 @@ pub const HTTP_STATUS_EXPIRED: StatusCode = StatusCode::NotFound;
|
|||
pub const HTTP_STATUS_UNAUTHORIZED: StatusCode = StatusCode::Unauthorized;
|
||||
|
||||
/// The recommended maximum upload size in bytes.
|
||||
pub const UPLOAD_SIZE_MAX_RECOMMENDED: u64 = 1024 * 1024 * 1024 * 1;
|
||||
pub const UPLOAD_SIZE_MAX_RECOMMENDED: u64 = 1024 * 1024 * 1024;
|
||||
|
||||
/// The maximum upload size in bytes.
|
||||
pub const UPLOAD_SIZE_MAX: u64 = 1024 * 1024 * 1024 * 2;
|
||||
|
|
|
@ -26,7 +26,7 @@ const KEY_AUTH_ITERATIONS: usize = 100;
|
|||
/// # Returns
|
||||
/// The output keying material, with the length as as specified in the `length`
|
||||
/// argument.
|
||||
fn hkdf<'a>(
|
||||
fn hkdf(
|
||||
length: usize,
|
||||
ikm: &[u8],
|
||||
info: Option<&[u8]>,
|
||||
|
|
|
@ -10,6 +10,6 @@ impl StatusCodeExt for StatusCode {
|
|||
fn err_text(&self) -> String {
|
||||
self.canonical_reason()
|
||||
.map(|text| format!("{} {}", self.as_u16(), text))
|
||||
.unwrap_or(format!("{}", self.as_u16()))
|
||||
.unwrap_or_else(|| format!("{}", self.as_u16()))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ impl Metadata {
|
|||
/// * iv: initialisation vector
|
||||
/// * name: file name
|
||||
/// * mime: file mimetype
|
||||
pub fn from(iv: &[u8], name: String, mime: Mime) -> Self {
|
||||
pub fn from(iv: &[u8], name: String, mime: &Mime) -> Self {
|
||||
Metadata {
|
||||
iv: b64::encode(iv),
|
||||
name,
|
||||
|
|
|
@ -17,11 +17,11 @@ use crypto::b64;
|
|||
// TODO: match any sub-path?
|
||||
// TODO: match URL-safe base64 chars for the file ID?
|
||||
// TODO: constrain the ID length?
|
||||
const SHARE_PATH_PATTERN: &'static str = r"^/?download/([[:alnum:]]{8,}={0,3})/?$";
|
||||
const SHARE_PATH_PATTERN: &str = r"^/?download/([[:alnum:]]{8,}={0,3})/?$";
|
||||
|
||||
/// A pattern for share URL fragments, capturing the file secret.
|
||||
// TODO: constrain the secret length?
|
||||
const SHARE_FRAGMENT_PATTERN: &'static str = r"^([a-zA-Z0-9-_+/]+)?\s*$";
|
||||
const SHARE_FRAGMENT_PATTERN: &str = r"^([a-zA-Z0-9-_+/]+)?\s*$";
|
||||
|
||||
/// A struct representing an uploaded file on a Send host.
|
||||
///
|
||||
|
@ -289,19 +289,20 @@ impl RemoteFile {
|
|||
/// This is ofcourse only done for properties that may be empty.
|
||||
///
|
||||
/// The file IDs are not asserted for equality.
|
||||
#[allow(useless_let_if_seq)]
|
||||
pub fn merge(&mut self, other: &RemoteFile, overwrite: bool) -> bool {
|
||||
// Remember whether anything was changed
|
||||
// Remember whether anything has changed
|
||||
let mut changed = false;
|
||||
|
||||
// Set the upload time
|
||||
if other.upload_at.is_some() && (self.upload_at.is_none() || overwrite) {
|
||||
self.upload_at = other.upload_at.clone();
|
||||
self.upload_at = other.upload_at;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
// Set the expire time
|
||||
if !other.expire_uncertain() && (self.expire_uncertain() || overwrite) {
|
||||
self.expire_at = other.expire_at.clone();
|
||||
self.expire_at = other.expire_at;
|
||||
self.expire_uncertain = other.expire_uncertain();
|
||||
changed = true;
|
||||
}
|
||||
|
@ -318,7 +319,7 @@ impl RemoteFile {
|
|||
changed = true;
|
||||
}
|
||||
|
||||
return changed;
|
||||
changed
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ impl EncryptedFileReader {
|
|||
/// returned.
|
||||
fn read_internal(&mut self, buf: &mut [u8]) -> usize {
|
||||
// Return if there is no data to read
|
||||
if self.internal_buf.is_empty() || buf.len() == 0 {
|
||||
if self.internal_buf.is_empty() || buf.is_empty() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -335,6 +335,11 @@ pub trait ProgressReporter: Send {
|
|||
pub trait ExactLengthReader {
|
||||
/// Get the exact length of the reader in bytes.
|
||||
fn len(&self) -> Result<u64, io::Error>;
|
||||
|
||||
/// Check whehter this extact length reader is emtpy.
|
||||
fn is_empty(&self) -> Result<bool, io::Error> {
|
||||
self.len().map(|l| l == 0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: ExactLengthReader + Read> ExactLengthReader for BufReader<R> {
|
||||
|
|
|
@ -18,6 +18,7 @@ use ffsend_api::action::metadata::{
|
|||
Metadata as ApiMetadata,
|
||||
};
|
||||
use ffsend_api::file::remote_file::{FileParseError, RemoteFile};
|
||||
use ffsend_api::reader::ProgressReporter;
|
||||
use ffsend_api::reqwest::Client;
|
||||
|
||||
use cmd::matcher::{
|
||||
|
@ -93,7 +94,7 @@ impl<'a> Download<'a> {
|
|||
|
||||
// Prepare the output path to use
|
||||
let target = Self::prepare_path(
|
||||
target,
|
||||
&target,
|
||||
metadata.metadata().name(),
|
||||
&matcher_main,
|
||||
);
|
||||
|
@ -104,7 +105,8 @@ impl<'a> Download<'a> {
|
|||
}
|
||||
|
||||
// Create a progress bar reporter
|
||||
let bar = Arc::new(Mutex::new(ProgressBar::new_download()));
|
||||
let progress_bar = Arc::new(Mutex::new(ProgressBar::new_download()));
|
||||
let progress_reader: Arc<Mutex<ProgressReporter>> = progress_bar;
|
||||
|
||||
// Execute an download action
|
||||
ApiDownload::new(
|
||||
|
@ -113,7 +115,7 @@ impl<'a> Download<'a> {
|
|||
password,
|
||||
false,
|
||||
Some(metadata),
|
||||
).invoke(&client, bar)?;
|
||||
).invoke(&client, &progress_reader)?;
|
||||
|
||||
// Add the file to the history
|
||||
#[cfg(feature = "history")]
|
||||
|
@ -138,12 +140,12 @@ impl<'a> Download<'a> {
|
|||
///
|
||||
/// The program will quit with an error message if a problem occurs.
|
||||
fn prepare_path(
|
||||
target: PathBuf,
|
||||
target: &PathBuf,
|
||||
name_hint: &str,
|
||||
main_matcher: &MainMatcher,
|
||||
) -> PathBuf {
|
||||
// Select the path to use
|
||||
let target = Self::select_path(target, name_hint);
|
||||
let target = Self::select_path(&target, name_hint);
|
||||
|
||||
// Ask to overwrite
|
||||
if target.exists() && !main_matcher.force() {
|
||||
|
@ -185,7 +187,7 @@ impl<'a> Download<'a> {
|
|||
),
|
||||
}
|
||||
|
||||
return target;
|
||||
target
|
||||
}
|
||||
|
||||
/// This methods prepares a full file path to use for the file to
|
||||
|
@ -195,7 +197,7 @@ impl<'a> Download<'a> {
|
|||
/// If no file name was given, the original file name is used.
|
||||
///
|
||||
/// The full path including the file name will be returned.
|
||||
fn select_path(target: PathBuf, name_hint: &str) -> PathBuf {
|
||||
fn select_path(target: &PathBuf, name_hint: &str) -> PathBuf {
|
||||
// If we're already working with a file, canonicalize and return
|
||||
if target.is_file() {
|
||||
match target.canonicalize() {
|
||||
|
@ -255,7 +257,7 @@ impl<'a> Download<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
target
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ use ffsend_api::action::upload::{
|
|||
Upload as ApiUpload,
|
||||
};
|
||||
use ffsend_api::config::{UPLOAD_SIZE_MAX, UPLOAD_SIZE_MAX_RECOMMENDED};
|
||||
use ffsend_api::reader::ProgressReporter;
|
||||
use ffsend_api::reqwest::Client;
|
||||
use self::tempfile::{
|
||||
Builder as TempBuilder,
|
||||
|
@ -106,7 +107,7 @@ impl<'a> Upload<'a> {
|
|||
let client = Client::new();
|
||||
|
||||
// Create a progress bar reporter
|
||||
let bar = Arc::new(Mutex::new(ProgressBar::new_upload()));
|
||||
let progress_bar = Arc::new(Mutex::new(ProgressBar::new_upload()));
|
||||
|
||||
// Build a parameters object to set for the file
|
||||
let params = {
|
||||
|
@ -142,14 +143,14 @@ impl<'a> Upload<'a> {
|
|||
.prefix(&format!(".{}-archive-", crate_name!()))
|
||||
.suffix(archive_extention)
|
||||
.tempfile()
|
||||
.map_err(|err| ArchiveError::TempFile(err))?
|
||||
.map_err(ArchiveError::TempFile)?
|
||||
);
|
||||
if let Some(tmp_archive) = &tmp_archive {
|
||||
// Get the path, and the actual file
|
||||
let archive_path = tmp_archive.path().clone().to_path_buf();
|
||||
let archive_path = tmp_archive.path().to_path_buf();
|
||||
let archive_file = tmp_archive.as_file()
|
||||
.try_clone()
|
||||
.map_err(|err| ArchiveError::CloneHandle(err))?;
|
||||
.map_err(ArchiveError::CloneHandle)?;
|
||||
|
||||
// Select the file name to use if not set
|
||||
if file_name.is_none() {
|
||||
|
@ -166,10 +167,10 @@ impl<'a> Upload<'a> {
|
|||
// Build an archiver and append the file
|
||||
let mut archiver = Archiver::new(archive_file);
|
||||
archiver.append_path(file_name.as_ref().unwrap(), &path)
|
||||
.map_err(|err| ArchiveError::AddFile(err))?;
|
||||
.map_err(ArchiveError::AddFile)?;
|
||||
|
||||
// Finish the archival process, writes the archive file
|
||||
archiver.finish().map_err(|err| ArchiveError::Write(err))?;
|
||||
archiver.finish().map_err(ArchiveError::Write)?;
|
||||
|
||||
// Append archive extention to name, set to upload archived file
|
||||
if let Some(ref mut file_name) = file_name {
|
||||
|
@ -179,6 +180,9 @@ impl<'a> Upload<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
// Build the progress reporter
|
||||
let progress_reporter: Arc<Mutex<ProgressReporter>> = progress_bar;
|
||||
|
||||
// Execute an upload action
|
||||
let file = ApiUpload::new(
|
||||
host,
|
||||
|
@ -186,7 +190,7 @@ impl<'a> Upload<'a> {
|
|||
file_name,
|
||||
matcher_upload.password(),
|
||||
params,
|
||||
).invoke(&client, bar)?;
|
||||
).invoke(&client, &progress_reporter)?;
|
||||
|
||||
// Get the download URL, and report it in the console
|
||||
let url = file.download_url(true);
|
||||
|
@ -199,7 +203,7 @@ impl<'a> Upload<'a> {
|
|||
|
||||
// Open the URL in the browser
|
||||
if matcher_upload.open() {
|
||||
if let Err(err) = open_url(url.clone()) {
|
||||
if let Err(err) = open_url(&url) {
|
||||
print_error(
|
||||
err.context("failed to open the URL in the browser")
|
||||
);
|
||||
|
@ -209,10 +213,8 @@ impl<'a> Upload<'a> {
|
|||
// Copy the URL in the user's clipboard
|
||||
#[cfg(feature = "clipboard")]
|
||||
{
|
||||
if matcher_upload.copy() {
|
||||
if set_clipboard(url.as_str().to_owned()).is_err() {
|
||||
print_error_msg("failed to copy the URL to the clipboard");
|
||||
}
|
||||
if matcher_upload.copy() && set_clipboard(url.as_str().to_owned()).is_err() {
|
||||
print_error_msg("failed to copy the URL to the clipboard");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ use super::matcher::{
|
|||
};
|
||||
#[cfg(feature = "history")]
|
||||
use super::matcher::HistoryMatcher;
|
||||
use super::cmd::{
|
||||
use super::subcmd::{
|
||||
CmdDelete,
|
||||
CmdDownload,
|
||||
CmdExists,
|
||||
|
@ -24,7 +24,7 @@ use super::cmd::{
|
|||
CmdUpload,
|
||||
};
|
||||
#[cfg(feature = "history")]
|
||||
use super::cmd::CmdHistory;
|
||||
use super::subcmd::CmdHistory;
|
||||
#[cfg(feature = "history")]
|
||||
use util::app_history_file_path_string;
|
||||
|
||||
|
|
|
@ -32,8 +32,8 @@ impl<'a: 'b, 'b> DownloadMatcher<'a> {
|
|||
/// will be used.
|
||||
pub fn output(&'a self) -> PathBuf {
|
||||
self.matches.value_of("output")
|
||||
.map(|path| PathBuf::from(path))
|
||||
.unwrap_or(PathBuf::from("./"))
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or_else(|| PathBuf::from("./"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ impl<'a: 'b, 'b> MainMatcher<'a> {
|
|||
pub fn history(&self) -> PathBuf {
|
||||
// Get the path
|
||||
let path = self.matches.value_of("history")
|
||||
.map(|path| PathBuf::from(path));
|
||||
.map(PathBuf::from);
|
||||
|
||||
// Ensure the path is correct
|
||||
match path {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
pub mod arg;
|
||||
pub mod cmd;
|
||||
pub mod subcmd;
|
||||
pub mod handler;
|
||||
pub mod matcher;
|
||||
|
||||
|
|
|
@ -17,10 +17,10 @@ use self::version_compare::{
|
|||
use util::{print_error, print_warning};
|
||||
|
||||
/// The minimum supported history file version.
|
||||
const VERSION_MIN: &'static str = "0.0.1";
|
||||
const VERSION_MIN: &str = "0.0.1";
|
||||
|
||||
/// The maximum supported history file version.
|
||||
const VERSION_MAX: &'static str = crate_version!();
|
||||
const VERSION_MAX: &str = crate_version!();
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct History {
|
||||
|
@ -105,7 +105,7 @@ impl History {
|
|||
if self.files.is_empty() {
|
||||
if path.is_file() {
|
||||
fs::remove_file(&path)
|
||||
.map_err(|err| SaveError::Delete(err))?;
|
||||
.map_err(SaveError::Delete)?;
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -189,9 +189,7 @@ impl History {
|
|||
/// If multiple files exist within the history that are equal, only one is returned.
|
||||
/// If no matching file was found, `None` is returned.
|
||||
pub fn get_file(&self, file: &RemoteFile) -> Option<&RemoteFile> {
|
||||
self.files.iter()
|
||||
.filter(|f| f.id() == file.id() && f.host() == file.host())
|
||||
.next()
|
||||
self.files.iter().find(|f| f.id() == file.id() && f.host() == file.host())
|
||||
}
|
||||
|
||||
/// Garbage collect (remove) all files that have been expired,
|
||||
|
|
|
@ -125,8 +125,8 @@ pub fn derive_file_properties(matcher_main: &MainMatcher, file: &mut RemoteFile)
|
|||
}
|
||||
|
||||
// Return whether any property was derived
|
||||
return f.has_secret() || f.has_owner_token();
|
||||
f.has_secret() || f.has_owner_token()
|
||||
},
|
||||
None => return false,
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -121,13 +121,13 @@ pub fn print_main_info() {
|
|||
// Print the main info
|
||||
println!("{} {}", crate_name!(), crate_version!());
|
||||
println!("Usage: {} [FLAGS] <SUBCOMMAND> ...", exe);
|
||||
println!("");
|
||||
println!("{}", crate_description!());
|
||||
println!("");
|
||||
println!();
|
||||
println!(crate_description!());
|
||||
println!();
|
||||
println!("Missing subcommand. Here are the most used:");
|
||||
println!(" {}", highlight(&format!("{} upload <FILE> ...", exe)));
|
||||
println!(" {}", highlight(&format!("{} download <URL> ...", exe)));
|
||||
println!("");
|
||||
println!();
|
||||
println!("To show all subcommands, features and other help:");
|
||||
println!(" {}", highlight(&format!("{} help [SUBCOMMAND]", exe)));
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ const PROGRESS_BAR_FPS_MILLIS: u64 = 200;
|
|||
|
||||
/// A progress bar reporter.
|
||||
pub struct ProgressBar<'a> {
|
||||
bar: Option<Pbr<Stdout>>,
|
||||
progress_bar: Option<Pbr<Stdout>>,
|
||||
msg_progress: &'a str,
|
||||
msg_finish: &'a str,
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ impl<'a> ProgressBar<'a> {
|
|||
/// Construct a new progress bar, with the given messages.
|
||||
pub fn new(msg_progress: &'a str, msg_finish: &'a str) -> ProgressBar<'a> {
|
||||
Self {
|
||||
bar: None,
|
||||
progress_bar: None,
|
||||
msg_progress,
|
||||
msg_finish,
|
||||
}
|
||||
|
@ -44,26 +44,26 @@ impl<'a> ProgressReporter for ProgressBar<'a> {
|
|||
/// Start the progress with the given total.
|
||||
fn start(&mut self, total: u64) {
|
||||
// Initialize the progress bar
|
||||
let mut bar = Pbr::new(total);
|
||||
bar.set_max_refresh_rate(
|
||||
let mut progress_bar = Pbr::new(total);
|
||||
progress_bar.set_max_refresh_rate(
|
||||
Some(Duration::from_millis(PROGRESS_BAR_FPS_MILLIS))
|
||||
);
|
||||
bar.set_units(Units::Bytes);
|
||||
bar.message(self.msg_progress);
|
||||
progress_bar.set_units(Units::Bytes);
|
||||
progress_bar.message(self.msg_progress);
|
||||
|
||||
self.bar = Some(bar);
|
||||
self.progress_bar = Some(progress_bar);
|
||||
}
|
||||
|
||||
/// A progress update.
|
||||
fn progress(&mut self, progress: u64) {
|
||||
self.bar.as_mut()
|
||||
self.progress_bar.as_mut()
|
||||
.expect("progress bar not yet instantiated, cannot set progress")
|
||||
.set(progress);
|
||||
}
|
||||
|
||||
/// Finish the progress.
|
||||
fn finish(&mut self) {
|
||||
self.bar.as_mut()
|
||||
self.progress_bar.as_mut()
|
||||
.expect("progress bar not yet instantiated")
|
||||
.finish_print(self.msg_finish);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ extern crate directories;
|
|||
extern crate fs2;
|
||||
extern crate open;
|
||||
|
||||
use std::borrow::Borrow;
|
||||
use std::env::current_exe;
|
||||
#[cfg(feature = "clipboard")]
|
||||
use std::error::Error as StdError;
|
||||
|
@ -40,9 +41,11 @@ pub fn print_success(msg: &str) {
|
|||
|
||||
/// Print the given error in a proper format for the user,
|
||||
/// with it's causes.
|
||||
pub fn print_error<E: Fail>(err: E) {
|
||||
pub fn print_error<E: Fail>(err: impl Borrow<E>) {
|
||||
// Report each printable error, count them
|
||||
let count = err.causes() .map(|err| format!("{}", err))
|
||||
let count = err.borrow()
|
||||
.causes()
|
||||
.map(|err| format!("{}", err))
|
||||
.filter(|err| !err.is_empty())
|
||||
.enumerate()
|
||||
.map(|(i, err)| if i == 0 {
|
||||
|
@ -56,8 +59,7 @@ pub fn print_error<E: Fail>(err: E) {
|
|||
if count == 0 {
|
||||
eprintln!("{} {}", highlight_error("error:"), "an undefined error occurred");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/// Print the given error message in a proper format for the user,
|
||||
/// with it's causes.
|
||||
pub fn print_error_msg<S>(err: S)
|
||||
|
@ -83,12 +85,12 @@ pub fn quit() -> ! {
|
|||
|
||||
/// Quit the application with an error code,
|
||||
/// and print the given error.
|
||||
pub fn quit_error<E: Fail>(err: E, hints: ErrorHints) -> ! {
|
||||
pub fn quit_error<E: Fail>(err: E, hints: impl Borrow<ErrorHints>) -> ! {
|
||||
// Print the error
|
||||
print_error(err);
|
||||
|
||||
// Print error hints
|
||||
hints.print();
|
||||
hints.borrow().print();
|
||||
|
||||
// Quit
|
||||
exit(1);
|
||||
|
@ -96,7 +98,7 @@ pub fn quit_error<E: Fail>(err: E, hints: ErrorHints) -> ! {
|
|||
|
||||
/// Quit the application with an error code,
|
||||
/// and print the given error message.
|
||||
pub fn quit_error_msg<S>(err: S, hints: ErrorHints) -> !
|
||||
pub fn quit_error_msg<S>(err: S, hints: impl Borrow<ErrorHints>) -> !
|
||||
where
|
||||
S: AsRef<str> + Display + Debug + Sync + Send + 'static
|
||||
{
|
||||
|
@ -247,8 +249,8 @@ pub fn highlight_info(msg: &str) -> ColoredString {
|
|||
|
||||
/// Open the given URL in the users default browser.
|
||||
/// The browsers exit statis is returned.
|
||||
pub fn open_url(url: Url) -> Result<ExitStatus, IoError> {
|
||||
open_path(url.as_str())
|
||||
pub fn open_url(url: impl Borrow<Url>) -> Result<ExitStatus, IoError> {
|
||||
open_path(url.borrow().as_str())
|
||||
}
|
||||
|
||||
/// Open the given path or URL using the program configured on the system.
|
||||
|
@ -538,15 +540,15 @@ pub fn format_duration(duration: &Duration) -> String {
|
|||
// Build a list of time units, define a list for time components
|
||||
let mut components = Vec::new();
|
||||
let units = [
|
||||
(1 * 60 * 60 * 24 * 7, "w"),
|
||||
(1 * 60 * 60 * 24, "d"),
|
||||
(1 * 60 * 60, "h"),
|
||||
(1 * 60, "m"),
|
||||
(60 * 60 * 24 * 7, "w"),
|
||||
(60 * 60 * 24, "d"),
|
||||
(60 * 60, "h"),
|
||||
(60, "m"),
|
||||
(1, "s"),
|
||||
];
|
||||
|
||||
// Fill the list of time components based on the units which fit
|
||||
for unit in units.iter() {
|
||||
for unit in &units {
|
||||
if secs >= unit.0 {
|
||||
components.push(format!("{}{}", secs / unit.0, unit.1));
|
||||
secs %= unit.0;
|
||||
|
@ -564,7 +566,7 @@ pub fn exe_name() -> String {
|
|||
.ok()
|
||||
.and_then(|p| p.file_name().map(|n| n.to_owned()))
|
||||
.and_then(|n| n.into_string().ok())
|
||||
.unwrap_or(crate_name!().into())
|
||||
.unwrap_or_else(|| crate_name!().into())
|
||||
}
|
||||
|
||||
/// Ensure that there is enough free disk space available at the given `path`,
|
||||
|
@ -620,7 +622,7 @@ pub fn app_project_dirs() -> ProjectDirs {
|
|||
|
||||
/// Get the default path to use for the history file.
|
||||
#[cfg(feature = "history")]
|
||||
pub fn app_history_file_path<'a>() -> PathBuf {
|
||||
pub fn app_history_file_path() -> PathBuf {
|
||||
app_project_dirs().cache_dir().join("history.toml")
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue