diff --git a/src/api/client.rs b/src/api/client.rs index f25b71f..663867c 100644 --- a/src/api/client.rs +++ b/src/api/client.rs @@ -6,15 +6,10 @@ macro_rules! api_url ( pub(crate) use api_url; -use std::{fmt, fs, path::Path}; +use std::fmt; use reqwest::Client; -use crate::{ - requests::{self, RateLimitInfo}, - Error, ImageInfo, Result, -}; - /// Imgur Client #[derive(Clone)] pub struct ImgurClient { @@ -29,92 +24,3 @@ impl fmt::Debug for ImgurClient { write!(f, "ImgurClient - client_id: {}", self.client_id) } } - -impl ImgurClient { - /// Create a new Imgur Client - /// ``` - /// use imgurs::ImgurClient; - /// - /// let client = ImgurClient::new("3e3ce0d7ac14d56"); - /// ``` - pub fn new(client_id: &str) -> Self { - let client_id = client_id.to_string(); - let client = Client::new(); - ImgurClient { client_id, client } - } - - /// Upload image to Imgur - /// ``` - /// use imgurs::ImgurClient; - /// - /// #[tokio::main] - /// async fn main() { - /// let client = ImgurClient::new("3e3ce0d7ac14d56"); - /// - /// client.upload_image("https://i.imgur.com/lFaGr1x.png").await.expect("upload image"); - /// } - /// ``` - pub async fn upload_image(&self, path: &str) -> Result { - let mut image = path.to_string(); - - // check if the specified file exists if not then check if it is a url - if Path::new(path).exists() { - let bytes = fs::read(path)?; - image = base64::encode(bytes) - } - // validate url adress - else if !validator::validate_url(path) { - Err(Error::InvalidUrlOrFile(path.to_string()))?; - } - - requests::upload_image(self, image).await - } - - /// Delete image from Imgur - /// ``` - /// use imgurs::ImgurClient; - /// - /// #[tokio::main] - /// async fn main() { - /// let client = ImgurClient::new("3e3ce0d7ac14d56"); - /// - /// let image = client.upload_image("https://i.imgur.com/lFaGr1x.png").await.expect("upload image"); - /// let deletehash = image.data.deletehash.unwrap(); - /// - /// client.delete_image(&deletehash).await.expect("delete image"); - /// } - /// ``` - pub async fn delete_image(&self, delete_hash: &str) -> Result<()> { - requests::delete_image(self, delete_hash).await - } - - /// Get Rame Limit of this Imgur Client - /// ``` - /// use imgurs::ImgurClient; - /// - /// #[tokio::main] - /// async fn main() { - /// let client = ImgurClient::new("3e3ce0d7ac14d56"); - /// - /// client.rate_limit().await.expect("get rate limit"); - /// } - /// ``` - pub async fn rate_limit(&self) -> Result { - requests::rate_limit(self).await - } - - /// Get image info from a Imgur - /// ``` - /// use imgurs::ImgurClient; - /// - /// #[tokio::main] - /// async fn main() { - /// let client = ImgurClient::new("3e3ce0d7ac14d56"); - /// - /// client.image_info("lFaGr1x").await.expect("delete image"); - /// } - /// ``` - pub async fn image_info(&self, id: &str) -> Result { - requests::get_image(self, id).await - } -} diff --git a/src/api/error.rs b/src/api/error.rs index ef66a96..0e315f4 100644 --- a/src/api/error.rs +++ b/src/api/error.rs @@ -12,27 +12,25 @@ pub enum Error { /// Invalid file path or URL adress #[error("{0} is not url or file path")] InvalidUrlOrFile(String), - /// Reqwest error + /// reqwest::Error #[error("reqwest error - {0}")] ReqwestError(reqwest::Error), - /// Io Error + /// std::io::Error #[error("io error - {0}")] IoError(std::io::Error), } -/// reqwest::Error impl From for Error { fn from(err: reqwest::Error) -> Self { Error::ReqwestError(err) } } -/// reqwest::Error impl From for Error { fn from(err: std::io::Error) -> Self { Error::IoError(err) } } -/// A `Result` alias where the `Err` case is `imgurs::Error`. +/// A `Result` alias where the `Err` case is `imgurs::Error` pub type Result = std::result::Result; diff --git a/src/api/image_type.rs b/src/api/image_type.rs index 25860ea..9f3b5c3 100644 --- a/src/api/image_type.rs +++ b/src/api/image_type.rs @@ -1,29 +1,48 @@ use serde_derive::{Deserialize, Serialize}; /// Image Info Response -#[derive(Debug, Serialize, Deserialize, Clone)] +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] pub struct ImageInfo { + /// Image Data pub data: ImageInfoData, + /// Request processed success or not. pub success: bool, + /// HTTP status code from API request. pub status: i32, } /// Image Info Reponse (`data` json) -#[derive(Debug, Serialize, Deserialize, Clone)] +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] pub struct ImageInfoData { + /// Image ID + /// e.g. `iDYNKJq` pub id: String, + /// Image title pub title: Option, + /// Description of this image pub description: Option, + /// Image uploaded time pub datetime: i32, + /// Image type + /// e.g. `image/png` #[serde(rename = "type")] pub img_type: String, + /// If image if animated (gif, etc) pub animated: bool, + /// Width of this image pub width: i32, + /// Height of this image pub height: i32, + /// Image size in bytes pub size: i32, + /// Unique image views pub views: i32, + /// Bandwidth used by this image pub bandwidth: i64, + /// If image is added to favorite pub favorite: bool, + /// Delete hash (only show after image upload) pub deletehash: Option, + /// Link of this image pub link: String, } diff --git a/src/api/mod.rs b/src/api/mod.rs index 6227b63..677b741 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -1,5 +1,4 @@ -pub mod requests; - +mod requests; mod client; mod error; mod image_type; @@ -10,3 +9,92 @@ pub use client::ImgurClient; pub use error::*; pub use image_type::*; pub use send_api_request::*; + +impl ImgurClient { + /// Create a new Imgur Client + /// ``` + /// use imgurs::ImgurClient; + /// + /// let client = ImgurClient::new("3e3ce0d7ac14d56"); + /// ``` + pub fn new(client_id: &str) -> Self { + let client_id = client_id.to_string(); + let client = reqwest::Client::new(); + ImgurClient { client_id, client } + } + + /// Upload image to Imgur + /// ``` + /// use imgurs::ImgurClient; + /// + /// #[tokio::main] + /// async fn main() { + /// let client = ImgurClient::new("3e3ce0d7ac14d56"); + /// + /// client.upload_image("https://i.imgur.com/lFaGr1x.png").await.expect("upload image"); + /// } + /// ``` + pub async fn upload_image(&self, path: &str) -> Result { + let mut image = path.to_string(); + + // check if the specified file exists if not then check if it is a url + if std::path::Path::new(path).exists() { + let bytes = std::fs::read(path)?; + image = base64::encode(bytes) + } + // validate url adress + else if !validator::validate_url(path) { + Err(Error::InvalidUrlOrFile(path.to_string()))?; + } + + requests::upload_image(self, image).await + } + + /// Delete image from Imgur + /// ``` + /// use imgurs::ImgurClient; + /// + /// #[tokio::main] + /// async fn main() { + /// let client = ImgurClient::new("3e3ce0d7ac14d56"); + /// + /// let image = client.upload_image("https://i.imgur.com/lFaGr1x.png").await.expect("upload image"); + /// let deletehash = image.data.deletehash.unwrap(); + /// + /// client.delete_image(&deletehash).await.expect("delete image"); + /// } + /// ``` + pub async fn delete_image(&self, delete_hash: &str) -> Result<()> { + requests::delete_image(self, delete_hash).await + } + + /// Get Rame Limit of this Imgur Client + /// ``` + /// use imgurs::ImgurClient; + /// + /// #[tokio::main] + /// async fn main() { + /// let client = ImgurClient::new("3e3ce0d7ac14d56"); + /// + /// client.rate_limit().await.expect("get rate limit"); + /// } + /// ``` + pub async fn rate_limit(&self) -> Result { + requests::rate_limit(self).await + } + + /// Get image info from a Imgur + /// ``` + /// use imgurs::ImgurClient; + /// + /// #[tokio::main] + /// async fn main() { + /// let client = ImgurClient::new("3e3ce0d7ac14d56"); + /// + /// client.image_info("lFaGr1x").await.expect("delete image"); + /// } + /// ``` + pub async fn image_info(&self, id: &str) -> Result { + requests::get_image(self, id).await + } +} diff --git a/src/lib.rs b/src/lib.rs index 968bcd1..1d3369e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,37 +28,69 @@ //! ``` //! use imgurs::ImgurClient; //! -//! let client = ImgurClient::new("client id"); +//! let client = ImgurClient::new("client_id"); //! ``` //! //! ## Image Upload //! ```no_run -//! // From URL -//! let info = client.upload_image("https://i.imgur.com/lFaGr1x.png").await?; +//! use imgurs::ImgurClient; //! -//! // From File -//! let info = client.upload_image("path/to/image.png").await?; +//! #[tokio::main] +//! async fn main() { +//! let client = ImgurClient::new("client_id"); +//! +//! // From URL +//! let info = client.upload_image("https://i.imgur.com/lFaGr1x.png").await.unwrap(); +//! println!("{:?}", info); +//! +//! // From File +//! let info = client.upload_image("path/to/file.png").await.unwrap(); +//! println!("{:?}", info); +//! } //! ``` //! //! ## Delete Image //! ```no_run -//! client.delete_image("Delete Hash").await?; // delete hash +//! use imgurs::ImgurClient; +//! +//! #[tokio::main] +//! async fn main() { +//! let client = ImgurClient::new("client_id"); +//! +//! client.delete_image("delete_hash").await.unwrap(); // delete hash +//! } //! ``` //! //! ## Get Image Info //! ```no_run -//! let info = client.image_info("lFaGr1x").await?; // image id +//! use imgurs::ImgurClient; //! -//! println!("{:?}", info); +//! #[tokio::main] +//! async fn main() { +//! let client = ImgurClient::new("client_id"); +//! +//! let info = client.image_info("lFaGr1x").await.unwrap(); // image id +//! +//! println!("{:?}", info); +//! } //! ``` //! //! ## Get Client RateLimit //! ```no_run -//! let info = client.rate_limit.await?; +//! use imgurs::ImgurClient; //! -//! println!("{:?}", info); +//! #[tokio::main] +//! async fn main() { +//! let client = ImgurClient::new("client_id"); +//! +//! let info = client.rate_limit().await.unwrap(); +//! +//! println!("{:?}", info); +//! } //! ``` +#![warn(missing_docs)] + mod api; pub use api::*;