Apply clippy suggestions

This commit is contained in:
timvisee 2018-05-17 02:09:52 +02:00
parent f0ca016f4a
commit b62f3fd343
No known key found for this signature in database
GPG key ID: 109CBA0BF74036C2
34 changed files with 126 additions and 119 deletions

View file

@ -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()
}
}

View file

@ -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()

View file

@ -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()
}
}

View file

@ -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(

View file

@ -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);

View 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);

View 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();

View file

@ -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)]

View file

@ -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;

View file

@ -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]>,

View file

@ -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()))
}
}

View file

@ -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,

View file

@ -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
}
}

View file

@ -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> {

View file

@ -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
}
}

View file

@ -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");
}
}

View file

@ -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;

View file

@ -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("./"))
}
}

View file

@ -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 {

View file

@ -1,5 +1,5 @@
pub mod arg;
pub mod cmd;
pub mod subcmd;
pub mod handler;
pub mod matcher;

View file

@ -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,

View file

@ -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,
}
}

View file

@ -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)));
}

View file

@ -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);
}

View file

@ -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")
}