|
@@ -1,27 +1,33 @@
|
|
//! URL shortening mechanics.
|
|
//! URL shortening mechanics.
|
|
|
|
|
|
use ffsend_api::{
|
|
use ffsend_api::{
|
|
|
|
+ api::request::{ensure_success, ResponseError},
|
|
url::{self, Url},
|
|
url::{self, Url},
|
|
- reqwest::Client,
|
|
|
|
|
|
+ reqwest::{self, Client},
|
|
};
|
|
};
|
|
use urlshortener::{
|
|
use urlshortener::{
|
|
providers::{Provider, self},
|
|
providers::{Provider, self},
|
|
request::{Method, Request},
|
|
request::{Method, Request},
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+/// An URL shortening result.
|
|
|
|
+type Result<T> = ::std::result::Result<T, Error>;
|
|
|
|
+
|
|
/// Shorten the given URL.
|
|
/// Shorten the given URL.
|
|
-pub fn shorten(client: &Client, url: &str) -> String {
|
|
|
|
|
|
+pub fn shorten(client: &Client, url: &str) -> Result<String> {
|
|
// TODO: allow selecting other shorteners
|
|
// TODO: allow selecting other shorteners
|
|
request(client, providers::request(url, &Provider::IsGd))
|
|
request(client, providers::request(url, &Provider::IsGd))
|
|
}
|
|
}
|
|
|
|
|
|
/// Shorten the given URL.
|
|
/// Shorten the given URL.
|
|
-pub fn shorten_url(client: &Client, url: &Url) -> Result<Url, url::ParseError> {
|
|
|
|
- Url::parse(&shorten(client, url.as_str()))
|
|
|
|
|
|
+pub fn shorten_url(client: &Client, url: &Url) -> Result<Url> {
|
|
|
|
+ Url::parse(
|
|
|
|
+ &shorten(client, url.as_str())?,
|
|
|
|
+ ).map_err(|err| err.into())
|
|
}
|
|
}
|
|
|
|
|
|
/// Do the request as given, return the response.
|
|
/// Do the request as given, return the response.
|
|
-fn request(client: &Client, req: Request) -> String {
|
|
|
|
|
|
+fn request(client: &Client, req: Request) -> Result<String> {
|
|
// Start the request builder
|
|
// Start the request builder
|
|
let mut builder = match req.method {
|
|
let mut builder = match req.method {
|
|
Method::Get => client.get(&req.url),
|
|
Method::Get => client.get(&req.url),
|
|
@@ -52,5 +58,43 @@ fn request(client: &Client, req: Request) -> String {
|
|
builder = builder.body(body);
|
|
builder = builder.body(body);
|
|
}
|
|
}
|
|
|
|
|
|
- builder.send().expect("failed to send shorten request").text().expect("failed to get text")
|
|
|
|
|
|
+ // Send the request, ensure success
|
|
|
|
+ let mut response = builder.send()
|
|
|
|
+ .map_err(Error::Request)?;
|
|
|
|
+ ensure_success(&response)?;
|
|
|
|
+
|
|
|
|
+ // Respond with the body text
|
|
|
|
+ response.text().map_err(Error::Malformed)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/// An URL shortening error.
|
|
|
|
+#[derive(Debug, Fail)]
|
|
|
|
+pub enum Error {
|
|
|
|
+ /// Failed to send the shortening request.
|
|
|
|
+ #[fail(display = "failed to send URL shorten request")]
|
|
|
|
+ Request(#[cause] reqwest::Error),
|
|
|
|
+
|
|
|
|
+ /// The server responded with a bad response.
|
|
|
|
+ #[fail(display = "failed to shorten URL, got bad response")]
|
|
|
|
+ Response(#[cause] ResponseError),
|
|
|
|
+
|
|
|
|
+ /// The server resonded with a malformed repsonse.
|
|
|
|
+ #[fail(display = "failed to shorten URL, got malformed response")]
|
|
|
|
+ Malformed(#[cause] reqwest::Error),
|
|
|
|
+
|
|
|
|
+ /// An error occurred while parsing the shortened URL.
|
|
|
|
+ #[fail(display = "failed to shorten URL, could not parse URL")]
|
|
|
|
+ Url(#[cause] url::ParseError)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+impl From<url::ParseError> for Error {
|
|
|
|
+ fn from(err: url::ParseError) -> Self {
|
|
|
|
+ Error::Url(err)
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+impl From<ResponseError> for Error {
|
|
|
|
+ fn from(err: ResponseError) -> Self {
|
|
|
|
+ Error::Response(err)
|
|
|
|
+ }
|
|
}
|
|
}
|