aboutsummaryrefslogtreecommitdiffstats
path: root/src/utils.rs
diff options
context:
space:
mode:
authorJokler <jokler.contact@gmail.com>2019-06-22 15:51:21 +0200
committerJokler <jokler.contact@gmail.com>2019-06-22 15:51:21 +0200
commit3592c7b6fb2522ff57c7f312b8927eb680d6dc5c (patch)
treed484a367c205afe43ba7327a888b06844fd24c0c /src/utils.rs
parent237f6ebe59c90d4ceddd9af6a8a19e562d304aaa (diff)
parenta92e622a0d42911e8e46239c3bde17169ed60c92 (diff)
downloadfrippy-3592c7b6fb2522ff57c7f312b8927eb680d6dc5c.tar.gz
frippy-3592c7b6fb2522ff57c7f312b8927eb680d6dc5c.zip
Merge branch 'dev'HEADv0.5.0master
Diffstat (limited to 'src/utils.rs')
-rw-r--r--src/utils.rs119
1 files changed, 85 insertions, 34 deletions
diff --git a/src/utils.rs b/src/utils.rs
index 06156be..ef4d419 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -1,49 +1,100 @@
-use std::str;
+use std::borrow::Cow;
use std::io::{self, Read};
+use std::time::Duration;
-use reqwest::Client;
-use reqwest::header::Connection;
+use reqwest::header::{CONNECTION, HeaderValue};
+use reqwest::{Client, ClientBuilder};
-use failure::ResultExt;
use self::error::{DownloadError, ErrorKind};
+use failure::ResultExt;
+
+#[derive(Clone, Debug)]
+pub struct Url<'a> {
+ url: Cow<'a, str>,
+ max_kib: Option<usize>,
+ timeout: Option<Duration>,
+}
-/// Downloads the file and converts it to a String.
-/// Any invalid bytes are converted to a replacement character.
-///
-/// The error indicated either a failed download or that the DownloadLimit was reached
-pub fn download(url: &str, max_kib: Option<usize>) -> Result<String, DownloadError> {
- let mut response = Client::new()
- .get(url)
- .header(Connection::close())
- .send()
- .context(ErrorKind::Connection)?;
-
- // 100 kibibyte buffer
- let mut buf = [0; 100 * 1024];
- let mut written = 0;
- let mut bytes = Vec::new();
-
- // Read until we reach EOF or max_kib KiB
- loop {
- let len = match response.read(&mut buf) {
- Ok(0) => break,
- Ok(len) => len,
- Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue,
- Err(e) => Err(e).context(ErrorKind::Read)?,
+impl<'a> From<String> for Url<'a> {
+ fn from(url: String) -> Self {
+ Url {
+ url: Cow::from(url),
+ max_kib: None,
+ timeout: None,
+ }
+ }
+}
+
+impl<'a> From<&'a str> for Url<'a> {
+ fn from(url: &'a str) -> Self {
+ Url {
+ url: Cow::from(url),
+ max_kib: None,
+ timeout: None,
+ }
+ }
+}
+
+impl<'a> Url<'a> {
+ pub fn max_kib(mut self, limit: usize) -> Self {
+ self.max_kib = Some(limit);
+ self
+ }
+
+ pub fn timeout(mut self, timeout: Duration) -> Self {
+ self.timeout = Some(timeout);
+ self
+ }
+
+ /// Downloads the file and converts it to a String.
+ /// Any invalid bytes are converted to a replacement character.
+ ///
+ /// The error indicated either a failed download or
+ /// that the limit set by max_kib() was reached.
+ pub fn request(&self) -> Result<String, DownloadError> {
+ let client = if let Some(timeout) = self.timeout {
+ ClientBuilder::new().timeout(timeout).build().unwrap()
+ } else {
+ Client::new()
};
- bytes.extend_from_slice(&buf);
- written += len;
+ let mut response = client
+ .get(self.url.as_ref())
+ .header(CONNECTION, HeaderValue::from_static("close"))
+ .send()
+ .context(ErrorKind::Connection)?;
- // Check if the file is too large to download
- if let Some(max_kib) = max_kib {
- if written > max_kib * 1024 {
- Err(ErrorKind::DownloadLimit)?;
+ // 100 kibibyte buffer
+ let mut buf = [0; 100 * 1024];
+ let mut written = 0;
+ let mut bytes = Vec::new();
+
+ // Read until we reach EOF or max_kib KiB
+ loop {
+ let len = match response.read(&mut buf) {
+ Ok(0) => break,
+ Ok(len) => len,
+ Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue,
+ Err(e) => Err(e).context(ErrorKind::Read)?,
+ };
+
+ bytes.extend_from_slice(&buf[..len]);
+ written += len;
+
+ // Check if the file is too large to download
+ if let Some(max_kib) = self.max_kib {
+ if written > max_kib * 1024 {
+ Err(ErrorKind::DownloadLimit)?;
+ }
}
}
+
+ Ok(String::from_utf8_lossy(&bytes).into_owned())
}
- Ok(String::from_utf8_lossy(&bytes).into_owned())
+ pub fn as_str(&self) -> &str {
+ &self.url
+ }
}
pub mod error {