diff --git a/src/client.rs b/src/client.rs index 47d36c2..84bf161 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,14 +1,14 @@ -use crate::error::{Error, Result}; -use crate::paths::access_management::{ - ApiVersionResponse, GetServicesResponse, SessionKeyResponse, VerifyAccessKeyResponse, +use crate::endpoints::access_management::{ + ApiVersion, ApiVersionResponse, GetServices, GetServicesResponse, SessionKey, + SessionKeyResponse, VerifyAccessKey, VerifyAccessKeyResponse, }; -use crate::paths::adding_files::{ - AddFileRequest, AddFileResponse, ArchiveFilesRequest, ArchiveFilesResponse, DeleteFilesRequest, - DeleteFilesResponse, UnarchiveFilesRequest, UnarchiveFilesResponse, UndeleteFilesRequest, - UndeleteFilesResponse, +use crate::endpoints::adding_files::{ + AddFile, AddFileRequest, AddFileResponse, ArchiveFiles, ArchiveFilesRequest, DeleteFiles, + DeleteFilesRequest, UnarchiveFiles, UnarchiveFilesRequest, UndeleteFiles, UndeleteFilesRequest, }; -use crate::paths::adding_tags::{AddTagsRequest, AddTagsResponse, CleanTagsResponse}; -use crate::paths::Path; +use crate::endpoints::adding_tags::{AddTags, AddTagsRequest, CleanTags, CleanTagsResponse}; +use crate::endpoints::Endpoint; +use crate::error::{Error, Result}; use crate::utils::string_list_to_json_array; use reqwest::Response; use serde::de::DeserializeOwned; @@ -23,6 +23,7 @@ pub struct Client { } impl Client { + /// Creates a new client to start requests against the hydrus api. pub fn new>(url: S, access_key: S) -> Result { Ok(Self { inner: reqwest::Client::new(), @@ -32,13 +33,13 @@ impl Client { } /// Starts a get request to the path associated with the return type - async fn get_and_parse( + async fn get_and_parse( &mut self, query: &Q, - ) -> Result { + ) -> Result { let response = self .inner - .get(format!("{}/{}", self.base_url, T::get_path())) + .get(format!("{}/{}", self.base_url, E::get_path())) .header(ACCESS_KEY_HEADER, &self.access_key) .query(query) .send() @@ -49,10 +50,10 @@ impl Client { } /// Stats a post request to the path associated with the return type - async fn post(&mut self, body: B) -> Result { + async fn post(&mut self, body: E::Request) -> Result { let response = self .inner - .post(format!("{}/{}", self.base_url, T::get_path())) + .post(format!("{}/{}", self.base_url, E::get_path())) .json(&body) .header(ACCESS_KEY_HEADER, &self.access_key) .send() @@ -62,20 +63,17 @@ impl Client { } /// Stats a post request and parses the body as json - async fn post_and_parse( - &mut self, - body: B, - ) -> Result { - let response = self.post::(body).await?; + async fn post_and_parse(&mut self, body: E::Request) -> Result { + let response = self.post::(body).await?; Self::extract_content(response).await } /// Stats a post request to the path associated with the return type - async fn post_binary(&mut self, data: Vec) -> Result { + async fn post_binary(&mut self, data: Vec) -> Result { let response = self .inner - .post(format!("{}/{}", self.base_url, T::get_path())) + .post(format!("{}/{}", self.base_url, E::get_path())) .body(data) .header(ACCESS_KEY_HEADER, &self.access_key) .header("Content-Type", "application/octet-stream") @@ -103,27 +101,27 @@ impl Client { /// Returns the current API version. It's being incremented every time the API changes. pub async fn api_version(&mut self) -> Result { - self.get_and_parse(&()).await + self.get_and_parse::(&()).await } /// Creates a new session key pub async fn session_key(&mut self) -> Result { - self.get_and_parse(&()).await + self.get_and_parse::(&()).await } /// Verifies if the access key is valid and returns some information about its permissions pub async fn verify_access_key(&mut self) -> Result { - self.get_and_parse(&()).await + self.get_and_parse::(&()).await } /// Returns the list of tag and file services of the client pub async fn get_services(&mut self) -> Result { - self.get_and_parse(&()).await + self.get_and_parse::(&()).await } /// Adds a file to hydrus pub async fn add_file>(&mut self, path: S) -> Result { - self.post_and_parse(AddFileRequest { + self.post_and_parse::(AddFileRequest { path: path.as_ref().to_string(), }) .await @@ -131,12 +129,12 @@ impl Client { /// Adds a file from binary data to hydrus pub async fn add_binary_file(&mut self, data: Vec) -> Result { - self.post_binary(data).await + self.post_binary::(data).await } /// Moves files with matching hashes to the trash pub async fn delete_files(&mut self, hashes: Vec) -> Result<()> { - self.post::(DeleteFilesRequest { hashes }) + self.post::(DeleteFilesRequest { hashes }) .await?; Ok(()) @@ -144,7 +142,7 @@ impl Client { /// Pulls files out of the trash by hash pub async fn undelete_files(&mut self, hashes: Vec) -> Result<()> { - self.post::(UndeleteFilesRequest { hashes }) + self.post::(UndeleteFilesRequest { hashes }) .await?; Ok(()) @@ -152,7 +150,7 @@ impl Client { /// Moves files from the inbox into the archive pub async fn archive_files(&mut self, hashes: Vec) -> Result<()> { - self.post::(ArchiveFilesRequest { hashes }) + self.post::(ArchiveFilesRequest { hashes }) .await?; Ok(()) @@ -160,24 +158,24 @@ impl Client { /// Moves files from the archive into the inbox pub async fn unarchive_files(&mut self, hashes: Vec) -> Result<()> { - self.post::(UnarchiveFilesRequest { - hashes, - }) - .await?; + self.post::(UnarchiveFilesRequest { hashes }) + .await?; Ok(()) } /// Returns the list of tags as the client would see them in a human friendly order pub async fn clean_tags(&mut self, tags: Vec) -> Result { - self.get_and_parse(&[("tags", string_list_to_json_array(tags))]) - .await + self.get_and_parse::(&[( + "tags", + string_list_to_json_array(tags), + )]) + .await } /// Adds tags to files with the given hashes pub async fn add_tags(&mut self, request: AddTagsRequest) -> Result<()> { - self.post::(request) - .await?; + self.post::(request).await?; Ok(()) } diff --git a/src/paths/access_management.rs b/src/endpoints/access_management.rs similarity index 58% rename from src/paths/access_management.rs rename to src/endpoints/access_management.rs index 4e182ce..96d759c 100644 --- a/src/paths/access_management.rs +++ b/src/endpoints/access_management.rs @@ -1,5 +1,5 @@ -use crate::paths::common::BasicServiceInfo; -use crate::paths::Path; +use crate::endpoints::common::BasicServiceInfo; +use crate::endpoints::Endpoint; use std::collections::HashMap; #[derive(Debug, Clone, Deserialize)] @@ -8,7 +8,12 @@ pub struct ApiVersionResponse { pub hydrus_version: u32, } -impl Path for ApiVersionResponse { +pub struct ApiVersion; + +impl Endpoint for ApiVersion { + type Request = (); + type Response = ApiVersionResponse; + fn get_path() -> String { String::from("api_version") } @@ -19,7 +24,12 @@ pub struct SessionKeyResponse { pub session_key: String, } -impl Path for SessionKeyResponse { +pub struct SessionKey; + +impl Endpoint for SessionKey { + type Request = (); + type Response = SessionKeyResponse; + fn get_path() -> String { String::from("session_key") } @@ -31,7 +41,12 @@ pub struct VerifyAccessKeyResponse { pub human_description: String, } -impl Path for VerifyAccessKeyResponse { +pub struct VerifyAccessKey; + +impl Endpoint for VerifyAccessKey { + type Request = (); + type Response = VerifyAccessKeyResponse; + fn get_path() -> String { String::from("verify_access_key") } @@ -40,7 +55,12 @@ impl Path for VerifyAccessKeyResponse { #[derive(Debug, Clone, Deserialize)] pub struct GetServicesResponse(pub HashMap>); -impl Path for GetServicesResponse { +pub struct GetServices; + +impl Endpoint for GetServices { + type Request = (); + type Response = GetServicesResponse; + fn get_path() -> String { String::from("get_services") } diff --git a/src/paths/adding_files.rs b/src/endpoints/adding_files.rs similarity index 54% rename from src/paths/adding_files.rs rename to src/endpoints/adding_files.rs index 45544ac..2ff9892 100644 --- a/src/paths/adding_files.rs +++ b/src/endpoints/adding_files.rs @@ -1,5 +1,5 @@ -use crate::paths::common::BasicHashList; -use crate::paths::Path; +use crate::endpoints::common::BasicHashList; +use crate::endpoints::Endpoint; #[derive(Debug, Clone, Serialize)] pub struct AddFileRequest { @@ -13,43 +13,61 @@ pub struct AddFileResponse { pub note: String, } -impl Path for AddFileResponse { +pub struct AddFile; + +impl Endpoint for AddFile { + type Request = AddFileRequest; + type Response = AddFileResponse; + fn get_path() -> String { String::from("add_files/add_file") } } pub type DeleteFilesRequest = BasicHashList; -pub struct DeleteFilesResponse; -impl Path for DeleteFilesResponse { +pub struct DeleteFiles; + +impl Endpoint for DeleteFiles { + type Request = DeleteFilesRequest; + type Response = (); + fn get_path() -> String { String::from("add_files/delete_files") } } pub type UndeleteFilesRequest = BasicHashList; -pub struct UndeleteFilesResponse; +pub struct UndeleteFiles; + +impl Endpoint for UndeleteFiles { + type Request = UndeleteFilesRequest; + type Response = (); -impl Path for UndeleteFilesResponse { fn get_path() -> String { String::from("add_files/undelete_files") } } pub type ArchiveFilesRequest = BasicHashList; -pub struct ArchiveFilesResponse; +pub struct ArchiveFiles; + +impl Endpoint for ArchiveFiles { + type Request = ArchiveFilesRequest; + type Response = (); -impl Path for ArchiveFilesResponse { fn get_path() -> String { String::from("add_files/archive_files") } } pub type UnarchiveFilesRequest = BasicHashList; -pub struct UnarchiveFilesResponse; +pub struct UnarchiveFiles; + +impl Endpoint for UnarchiveFiles { + type Request = UndeleteFilesRequest; + type Response = (); -impl Path for UnarchiveFilesResponse { fn get_path() -> String { String::from("add_files/unarchive_files") } diff --git a/src/paths/adding_tags.rs b/src/endpoints/adding_tags.rs similarity index 94% rename from src/paths/adding_tags.rs rename to src/endpoints/adding_tags.rs index 5fe69ac..04c09d8 100644 --- a/src/paths/adding_tags.rs +++ b/src/endpoints/adding_tags.rs @@ -1,4 +1,4 @@ -use crate::paths::Path; +use crate::endpoints::Endpoint; use std::collections::HashMap; #[derive(Debug, Clone, Deserialize)] @@ -6,7 +6,12 @@ pub struct CleanTagsResponse { pub tags: Vec, } -impl Path for CleanTagsResponse { +pub struct CleanTags; + +impl Endpoint for CleanTags { + type Request = (); + type Response = CleanTagsResponse; + fn get_path() -> String { String::from("add_tags/clean_tags") } @@ -19,9 +24,12 @@ pub struct AddTagsRequest { pub service_names_to_actions_to_tags: HashMap>>, } -pub struct AddTagsResponse; +pub struct AddTags; + +impl Endpoint for AddTags { + type Request = AddTagsRequest; + type Response = (); -impl Path for AddTagsResponse { fn get_path() -> String { String::from("add_tags/add_tags") } diff --git a/src/paths/common.rs b/src/endpoints/common.rs similarity index 100% rename from src/paths/common.rs rename to src/endpoints/common.rs diff --git a/src/endpoints/mod.rs b/src/endpoints/mod.rs new file mode 100644 index 0000000..e71c3c8 --- /dev/null +++ b/src/endpoints/mod.rs @@ -0,0 +1,14 @@ +use serde::de::DeserializeOwned; +use serde::Serialize; + +pub mod access_management; +pub mod adding_files; +pub mod adding_tags; +pub mod common; + +pub trait Endpoint { + type Request: Serialize; + type Response: DeserializeOwned; + + fn get_path() -> String; +} diff --git a/src/lib.rs b/src/lib.rs index 7882f14..6764298 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,7 +6,7 @@ //! ## Usage Example //! ``` //! use hydrus_api::Client; -//! use hydrus_api::paths::adding_tags::{AddTagsRequestBuilder, TagAction}; +//! use hydrus_api::endpoints::adding_tags::{AddTagsRequestBuilder, TagAction}; //! use std::env; //! # #[tokio::test] //! # async fn doctest() { @@ -35,8 +35,8 @@ extern crate serde_derive; pub mod client; +pub mod endpoints; mod error; -pub mod paths; pub(crate) mod utils; pub use client::Client; diff --git a/src/paths/mod.rs b/src/paths/mod.rs deleted file mode 100644 index b88fbec..0000000 --- a/src/paths/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -pub mod access_management; -pub mod adding_files; -pub mod adding_tags; -pub mod common; - -pub trait Path { - fn get_path() -> String; -} diff --git a/tests/test_adding_tags.rs b/tests/test_adding_tags.rs index 15aa1d9..eb98b11 100644 --- a/tests/test_adding_tags.rs +++ b/tests/test_adding_tags.rs @@ -1,4 +1,4 @@ -use hydrus_api::paths::adding_tags::{AddTagsRequestBuilder, TagAction}; +use hydrus_api::endpoints::adding_tags::{AddTagsRequestBuilder, TagAction}; mod common; #[tokio::test]