From 7260eb825ad982c735ae35e96341cda890e32cb9 Mon Sep 17 00:00:00 2001 From: trivernis Date: Sun, 27 Feb 2022 12:27:43 +0100 Subject: [PATCH] Add support for adding tags to services by service keys Signed-off-by: trivernis --- src/api_core/adding_tags.rs | 58 +++++++++++++------------ src/api_core/client.rs | 1 + src/api_core/common.rs | 16 +++++++ src/wrapper/builders/tagging_builder.rs | 15 ++++--- src/wrapper/hydrus_file.rs | 9 ++-- src/wrapper/service.rs | 7 +++ tests/client/test_adding_tags.rs | 12 ++++- tests/wrapper/test_hydrus.rs | 2 +- 8 files changed, 82 insertions(+), 38 deletions(-) diff --git a/src/api_core/adding_tags.rs b/src/api_core/adding_tags.rs index 91c883f..1c9aafe 100644 --- a/src/api_core/adding_tags.rs +++ b/src/api_core/adding_tags.rs @@ -1,3 +1,4 @@ +use crate::api_core::common::ServiceIdentifier; use crate::api_core::Endpoint; use std::collections::HashMap; @@ -21,7 +22,9 @@ impl Endpoint for CleanTags { pub struct AddTagsRequest { pub hashes: Vec, pub service_names_to_tags: HashMap>, + pub service_keys_to_tags: HashMap>, pub service_names_to_actions_to_tags: HashMap>>, + pub service_keys_to_actions_to_tags: HashMap>>, } pub struct AddTags; @@ -35,10 +38,13 @@ impl Endpoint for AddTags { } } +#[derive(Default)] pub struct AddTagsRequestBuilder { hashes: Vec, service_names_to_tags: HashMap>, + service_keys_to_tags: HashMap>, service_names_to_actions_to_tags: HashMap>>, + service_keys_to_actions_to_tags: HashMap>>, } /// List of actions for a given tag @@ -78,16 +84,6 @@ impl TagAction { } } -impl Default for AddTagsRequestBuilder { - fn default() -> Self { - Self { - hashes: vec![], - service_names_to_tags: Default::default(), - service_names_to_actions_to_tags: Default::default(), - } - } -} - impl AddTagsRequestBuilder { /// Adds a file hash to the request pub fn add_hash>(mut self, hash: S) -> Self { @@ -104,41 +100,48 @@ impl AddTagsRequestBuilder { } /// Adds a single tag for a given service - pub fn add_tag, S2: AsRef>(mut self, service_name: S1, tag: S2) -> Self { - if let Some(mappings) = self.service_names_to_tags.get_mut(service_name.as_ref()) { + pub fn add_tag>(mut self, service_id: ServiceIdentifier, tag: S) -> Self { + let (service, relevant_mappings) = match service_id { + ServiceIdentifier::Name(name) => (name, &mut self.service_names_to_tags), + ServiceIdentifier::Key(key) => (key, &mut self.service_keys_to_tags), + }; + if let Some(mappings) = relevant_mappings.get_mut(&service) { mappings.push(tag.as_ref().into()) } else { - self.service_names_to_tags - .insert(service_name.as_ref().into(), vec![tag.as_ref().into()]); + relevant_mappings.insert(service, vec![tag.as_ref().into()]); } self } /// Adds multiple tags for a given service - pub fn add_tags>(mut self, service_name: S1, mut tags: Vec) -> Self { - if let Some(mappings) = self.service_names_to_tags.get_mut(service_name.as_ref()) { + pub fn add_tags(mut self, service_id: ServiceIdentifier, mut tags: Vec) -> Self { + let (service, relevant_mappings) = match service_id { + ServiceIdentifier::Name(name) => (name, &mut self.service_names_to_tags), + ServiceIdentifier::Key(key) => (key, &mut self.service_keys_to_tags), + }; + if let Some(mappings) = relevant_mappings.get_mut(&service) { mappings.append(&mut tags); } else { - self.service_names_to_tags - .insert(service_name.as_ref().into(), tags); + relevant_mappings.insert(service, tags); } self } /// Adds one tag for a given service with a defined action - pub fn add_tag_with_action, S2: AsRef>( + pub fn add_tag_with_action>( mut self, - service_name: S1, - tag: S2, + service_id: ServiceIdentifier, + tag: S, action: TagAction, ) -> Self { + let (service, relevant_mappings) = match service_id { + ServiceIdentifier::Name(name) => (name, &mut self.service_names_to_actions_to_tags), + ServiceIdentifier::Key(key) => (key, &mut self.service_keys_to_actions_to_tags), + }; let action_id = action.into_id(); - if let Some(actions) = self - .service_names_to_actions_to_tags - .get_mut(service_name.as_ref()) - { + if let Some(actions) = relevant_mappings.get_mut(&service) { if let Some(tags) = actions.get_mut(&action_id.to_string()) { tags.push(tag.as_ref().into()); } else { @@ -147,8 +150,7 @@ impl AddTagsRequestBuilder { } else { let mut actions = HashMap::new(); actions.insert(action_id.to_string(), vec![tag.as_ref().into()]); - self.service_names_to_actions_to_tags - .insert(service_name.as_ref().into(), actions); + relevant_mappings.insert(service, actions); } self } @@ -158,7 +160,9 @@ impl AddTagsRequestBuilder { AddTagsRequest { hashes: self.hashes, service_names_to_tags: self.service_names_to_tags, + service_keys_to_tags: self.service_keys_to_tags, service_names_to_actions_to_tags: self.service_names_to_actions_to_tags, + service_keys_to_actions_to_tags: self.service_keys_to_actions_to_tags, } } } diff --git a/src/api_core/client.rs b/src/api_core/client.rs index 7905356..44a3662 100644 --- a/src/api_core/client.rs +++ b/src/api_core/client.rs @@ -228,6 +228,7 @@ impl Client { } /// Adds tags to files with the given hashes + #[tracing::instrument(skip(self), level = "debug")] pub async fn add_tags(&self, request: AddTagsRequest) -> Result<()> { self.post::(request).await?; diff --git a/src/api_core/common.rs b/src/api_core/common.rs index a23f9cb..26809e1 100644 --- a/src/api_core/common.rs +++ b/src/api_core/common.rs @@ -6,6 +6,22 @@ pub struct BasicServiceInfo { pub service_key: String, } +#[derive(Clone, Debug, Serialize, Deserialize, Hash, PartialOrd, PartialEq, Ord, Eq)] +pub enum ServiceIdentifier { + Name(String), + Key(String), +} + +impl ServiceIdentifier { + pub fn name(name: S) -> Self { + Self::Name(name.to_string()) + } + + pub fn key(key: S) -> Self { + Self::Key(key.to_string()) + } +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct BasicHashList { pub hashes: Vec, diff --git a/src/wrapper/builders/tagging_builder.rs b/src/wrapper/builders/tagging_builder.rs index c80fa8b..07f85b0 100644 --- a/src/wrapper/builders/tagging_builder.rs +++ b/src/wrapper/builders/tagging_builder.rs @@ -1,6 +1,6 @@ use crate::api_core::adding_tags::{AddTagsRequestBuilder, TagAction}; +use crate::api_core::common::ServiceIdentifier; use crate::error::Result; -use crate::wrapper::service::ServiceName; use crate::wrapper::tag::Tag; use crate::Client; use std::collections::HashMap; @@ -8,7 +8,7 @@ use std::collections::HashMap; pub struct TaggingBuilder { client: Client, hashes: Vec, - tag_mappings: HashMap>>, + tag_mappings: HashMap>>, } impl TaggingBuilder { @@ -28,12 +28,17 @@ impl TaggingBuilder { } /// Adds a single tag for a given service - pub fn add_tag(self, service: ServiceName, action: TagAction, tag: Tag) -> Self { + pub fn add_tag(self, service: ServiceIdentifier, action: TagAction, tag: Tag) -> Self { self.add_tags(service, action, vec![tag]) } /// Adds tags with actions for the given service - pub fn add_tags(mut self, service: ServiceName, action: TagAction, mut tags: Vec) -> Self { + pub fn add_tags( + mut self, + service: ServiceIdentifier, + action: TagAction, + mut tags: Vec, + ) -> Self { let service_action_mappings = if let Some(service_action_mappings) = self.tag_mappings.get_mut(&service) { service_action_mappings @@ -57,7 +62,7 @@ impl TaggingBuilder { for (action, tags) in action_tag_mappings { for tag in tags { request = request.add_tag_with_action( - service.0.clone(), + service.clone().into(), tag.to_string(), action.clone(), ); diff --git a/src/wrapper/hydrus_file.rs b/src/wrapper/hydrus_file.rs index a0312ea..d079078 100644 --- a/src/wrapper/hydrus_file.rs +++ b/src/wrapper/hydrus_file.rs @@ -217,7 +217,7 @@ impl HydrusFile { let hash = self.hash().await?; let request = AddTagsRequestBuilder::default() .add_hash(hash) - .add_tags(service.0, tag_list_to_string_list(tags)) + .add_tags(service.into(), tag_list_to_string_list(tags)) .build(); self.client.add_tags(request).await @@ -234,8 +234,11 @@ impl HydrusFile { let mut reqwest = AddTagsRequestBuilder::default().add_hash(hash); for tag in tags { - reqwest = - reqwest.add_tag_with_action(service.0.clone(), tag.to_string(), action.clone()); + reqwest = reqwest.add_tag_with_action( + service.clone().into(), + tag.to_string(), + action.clone(), + ); } self.client.add_tags(reqwest.build()).await diff --git a/src/wrapper/service.rs b/src/wrapper/service.rs index f85998e..c8b9ab1 100644 --- a/src/wrapper/service.rs +++ b/src/wrapper/service.rs @@ -5,6 +5,7 @@ use crate::api_core::access_management::{ SERVICE_TYPE_TAG_REPOSITORIES, SERVICE_TYPE_TRASH, }; +use crate::api_core::common::ServiceIdentifier; use crate::error::Error; use crate::wrapper::builders::search_builder::SearchBuilder; use crate::Client; @@ -96,6 +97,12 @@ impl Display for ServiceName { } } +impl Into for ServiceName { + fn into(self) -> ServiceIdentifier { + ServiceIdentifier::Name(self.0) + } +} + #[derive(Clone)] pub struct Service { client: Client, diff --git a/tests/client/test_adding_tags.rs b/tests/client/test_adding_tags.rs index 2dacb13..467d08f 100644 --- a/tests/client/test_adding_tags.rs +++ b/tests/client/test_adding_tags.rs @@ -1,5 +1,6 @@ use super::super::common; use hydrus_api::api_core::adding_tags::{AddTagsRequestBuilder, TagAction}; +use hydrus_api::api_core::common::ServiceIdentifier; #[tokio::test] async fn it_cleans_tags() { @@ -21,8 +22,15 @@ async fn it_adds_tags() { let client = common::get_client(); let request = AddTagsRequestBuilder::default() .add_hash("0000000000000000000000000000000000000000000000000000000000000000") // valid hash, I hope no files are affected - .add_tags("my tags", vec!["beach".into(), "summer".into()]) - .add_tag_with_action("my tags", "rain", TagAction::DeleteFromLocalService) + .add_tags( + ServiceIdentifier::name("my tags"), + vec!["beach".into(), "summer".into()], + ) + .add_tag_with_action( + ServiceIdentifier::name("my tags"), + "rain", + TagAction::DeleteFromLocalService, + ) .build(); client.add_tags(request).await.unwrap(); } diff --git a/tests/wrapper/test_hydrus.rs b/tests/wrapper/test_hydrus.rs index 7f10325..777d1d3 100644 --- a/tests/wrapper/test_hydrus.rs +++ b/tests/wrapper/test_hydrus.rs @@ -60,7 +60,7 @@ async fn it_adds_tags() { hydrus .tagging() .add_tag( - ServiceName::my_tags(), + ServiceName::my_tags().into(), TagAction::AddToLocalService, "summer".into(), )