From 982f74797608c23d0d916979e181afd434969f0c Mon Sep 17 00:00:00 2001 From: trivernis Date: Sun, 15 Jan 2023 12:55:27 +0100 Subject: [PATCH] Add add_tags/search_tags core api --- src/api_core/client.rs | 15 +++++ src/api_core/endpoints/adding_tags.rs | 88 +++++++++++++++++++++++++++ tests/client/test_adding_tags.rs | 21 ++++++- 3 files changed, 123 insertions(+), 1 deletion(-) diff --git a/src/api_core/client.rs b/src/api_core/client.rs index 3df1477..6e195ab 100644 --- a/src/api_core/client.rs +++ b/src/api_core/client.rs @@ -41,6 +41,8 @@ use serde::Serialize; use std::collections::HashMap; use std::fmt::Debug; +use super::endpoints::adding_tags::{SearchTags, SearchTagsResponse, TagSearchOptions}; + const ACCESS_KEY_HEADER: &str = "Hydrus-Client-API-Access-Key"; const CONTENT_TYPE_HEADER: &str = "Content-Type"; const ACCEPT_HEADER: &str = "Accept"; @@ -196,6 +198,19 @@ impl Client { Ok(()) } + /// Searches for tags by name + #[tracing::instrument(skip(self), level = "debug")] + pub async fn search_tags( + &self, + query: S, + options: TagSearchOptions, + ) -> Result { + let mut args = options.into_query_args(); + args.push(("search", query.to_string())); + self.get_and_parse::(&args) + .await + } + /// Searches for files #[tracing::instrument(skip(self), level = "debug")] pub async fn search_files( diff --git a/src/api_core/endpoints/adding_tags.rs b/src/api_core/endpoints/adding_tags.rs index 8ac4363..e7c7507 100644 --- a/src/api_core/endpoints/adding_tags.rs +++ b/src/api_core/endpoints/adding_tags.rs @@ -166,3 +166,91 @@ impl AddTagsRequestBuilder { } } } + +pub struct SearchTags; + +impl Endpoint for SearchTags { + type Request = (); + + type Response = SearchTagsResponse; + + fn path() -> String { + String::from("add_tags/search_tags") + } +} + +#[derive(Debug, Deserialize)] +pub struct SearchTagsResponse { + pub tags: Vec, +} + +#[derive(Debug, Deserialize)] +pub struct TagWithCount { + /// The name of the tag + pub value: String, + /// The count of how many times it was found in the database + pub count: u64, +} + +#[derive(Debug, Default)] +pub struct TagSearchOptions { + /// And optional filter for the service the tags should belong to + pub tag_service: Option, + /// Controls how the tags in the result should be displayed + pub display_type: TagDisplayType, +} + +#[derive(Debug)] +pub enum TagDisplayType { + /// Returns tags as stored in the hydrus database + Storage, + /// Returns tags as displayed by hydrus + Display, +} + +impl Default for TagDisplayType { + fn default() -> Self { + Self::Storage + } +} + +impl TagDisplayType { + fn to_api_string(&self) -> &'static str { + match self { + TagDisplayType::Storage => "storage", + TagDisplayType::Display => "display", + } + } +} + +impl TagSearchOptions { + /// Sets the display type of the search result + pub fn display_type(mut self, display_type: TagDisplayType) -> Self { + self.display_type = display_type; + self + } + + /// Adds a filter for the tag service that the tags we're searching for + /// should belong to. + pub fn tag_service(mut self, tag_service: ServiceIdentifier) -> Self { + self.tag_service = Some(tag_service); + self + } + + pub(crate) fn into_query_args(self) -> Vec<(&'static str, String)> { + let mut args = Vec::new(); + + if let Some(service) = self.tag_service { + match service { + ServiceIdentifier::Name(name) => args.push(("tag_service_name", name)), + ServiceIdentifier::Key(key) => args.push(("tag_service_key", key)), + } + } + args.push(( + "tag_display_type", + self.display_type.to_api_string().to_string(), + )); + + args + } +} diff --git a/tests/client/test_adding_tags.rs b/tests/client/test_adding_tags.rs index 5c43792..65e5f21 100644 --- a/tests/client/test_adding_tags.rs +++ b/tests/client/test_adding_tags.rs @@ -1,7 +1,9 @@ use super::super::common; use crate::common::test_data::EMPTY_HASH; use hydrus_api::api_core::common::ServiceIdentifier; -use hydrus_api::api_core::endpoints::adding_tags::{AddTagsRequestBuilder, TagAction}; +use hydrus_api::api_core::endpoints::adding_tags::{ + AddTagsRequestBuilder, TagAction, TagDisplayType, TagSearchOptions, +}; #[tokio::test] async fn it_cleans_tags() { @@ -36,3 +38,20 @@ async fn it_adds_tags() { .build(); client.add_tags(request).await.unwrap(); } + +/// This test requires that searching for "*" is permitted in hydrus +#[tokio::test] +async fn it_searches_for_tags() { + #![allow(deprecated)] + let client = common::get_client(); + let response = client + .search_tags( + "*", + TagSearchOptions::default() + .display_type(TagDisplayType::Display) + .tag_service(ServiceIdentifier::name("public tag repository")), + ) + .await + .unwrap(); + assert!(response.tags.is_empty() == false) +}