diff --git a/src/wrapper/builders/mod.rs b/src/wrapper/builders/mod.rs index 7ab8348..0584473 100644 --- a/src/wrapper/builders/mod.rs +++ b/src/wrapper/builders/mod.rs @@ -1,3 +1,4 @@ pub mod import_builder; pub mod tagging_builder; pub mod tag_builder; +pub mod search_builder; diff --git a/src/wrapper/builders/search_builder.rs b/src/wrapper/builders/search_builder.rs new file mode 100644 index 0000000..7c6c35f --- /dev/null +++ b/src/wrapper/builders/search_builder.rs @@ -0,0 +1,115 @@ +use crate::api_core::searching_and_fetching_files::FileSearchOptions; +use crate::error::Result; +use crate::utils::tag_list_to_string_list; +use crate::wrapper::hydrus_file::HydrusFile; +use crate::wrapper::service::ServiceName; +use crate::wrapper::tag::Tag; +use crate::Client; + +pub enum SortType { + FileSize, + Duration, + ImportTime, + FileType, + Random, + Width, + Height, + Ratio, + NumberOfPixels, + NumberOfTags, + NumberOfMediaViewers, + MediaViewTime, + Bitrate, + HasAudio, + ModifiedTime, + Framerate, + NumberOfFrames, +} + +#[derive(Clone, Debug)] +pub struct SearchBuilder { + client: Client, + tags: Vec, + options: FileSearchOptions, +} + +impl SearchBuilder { + pub(crate) fn new(client: Client) -> Self { + Self { + client, + tags: Vec::new(), + options: FileSearchOptions::new(), + } + } + + /// Add multiple tags to filter by + pub fn add_tags(mut self, mut tags: Vec) -> Self { + self.tags.append(&mut tags); + self + } + + /// Add a tag to filter by + pub fn add_tag(mut self, tag: Tag) -> Self { + self.tags.push(tag); + self + } + + /// Sets the sort type + pub fn sort_by(mut self, sort_type: SortType) -> Self { + self.options = self.options.sort_type(sort_type as u8); + self + } + + /// Sorts descending + pub fn sort_descending(mut self) -> Self { + self.options = self.options.desc(); + self + } + + /// Sorts ascending + pub fn sort_ascending(mut self) -> Self { + self.options = self.options.asc(); + self + } + + /// Sets the file service name to search in + pub fn file_service_name(mut self, service: ServiceName) -> Self { + self.options = self.options.file_service_name(service); + self + } + + /// Sets the tag service to search by + pub fn tag_service_name(mut self, service: ServiceName) -> Self { + self.options = self.options.tag_service_name(service); + self + } + + /// Sets the file service key. This option is preferred over + /// setting it by name because it's faster + pub fn file_service_key(mut self, key: S) -> Self { + self.options = self.options.file_service_key(key); + self + } + + /// Sets the tag service key. This option is preferred over + /// setting it by name because it's faster + pub fn tag_service_key(mut self, key: S) -> Self { + self.options = self.options.tag_service_key(key); + self + } + + /// Runs the search + pub async fn run(self) -> Result> { + let client = self.client.clone(); + let response = client + .search_files(tag_list_to_string_list(self.tags), self.options) + .await?; + let files = response + .file_ids + .into_iter() + .map(|id| HydrusFile::from_id(client.clone(), id)) + .collect(); + + Ok(files) + } +} diff --git a/src/wrapper/hydrus.rs b/src/wrapper/hydrus.rs index 390e92f..031ee28 100644 --- a/src/wrapper/hydrus.rs +++ b/src/wrapper/hydrus.rs @@ -1,14 +1,12 @@ use crate::api_core::common::FileIdentifier; -use crate::api_core::searching_and_fetching_files::FileSearchOptions; use crate::error::Result; -use crate::utils::tag_list_to_string_list; use crate::wrapper::address::Address; use crate::wrapper::builders::import_builder::ImportBuilder; +use crate::wrapper::builders::search_builder::SearchBuilder; use crate::wrapper::builders::tagging_builder::TaggingBuilder; use crate::wrapper::hydrus_file::HydrusFile; use crate::wrapper::page::HydrusPage; use crate::wrapper::service::Services; -use crate::wrapper::tag::Tag; use crate::wrapper::url::Url; use crate::wrapper::version::Version; use crate::Client; @@ -83,19 +81,9 @@ impl Hydrus { TaggingBuilder::new(self.client.clone()) } - /// Searches for files that have the given tags and returns a list of hydrus files as a result - pub async fn search(&self, tags: Vec) -> Result> { - let search_result = self - .client - .search_files(tag_list_to_string_list(tags), FileSearchOptions::new()) - .await?; - let files = search_result - .file_ids - .into_iter() - .map(|id| HydrusFile::from_id(self.client.clone(), id)) - .collect(); - - Ok(files) + /// Starts a request to search for files + pub fn search(&self) -> SearchBuilder { + SearchBuilder::new(self.client.clone()) } /// Returns a hydrus page by page key diff --git a/tests/wrapper/test_hydrus.rs b/tests/wrapper/test_hydrus.rs index 525c203..e4866b8 100644 --- a/tests/wrapper/test_hydrus.rs +++ b/tests/wrapper/test_hydrus.rs @@ -1,5 +1,6 @@ use super::super::common; use hydrus_api::api_core::adding_tags::TagAction; +use hydrus_api::wrapper::builders::search_builder::SortType; use hydrus_api::wrapper::service::{ServiceName, ServiceType}; use hydrus_api::wrapper::url::UrlType; @@ -36,7 +37,10 @@ async fn it_retrieves_url_information() { async fn it_searches() { let hydrus = common::get_hydrus(); hydrus - .search(vec!["character:megumin".into()]) + .search() + .add_tag("character:megumin".into()) + .sort_by(SortType::ModifiedTime) + .run() .await .unwrap(); } diff --git a/tests/wrapper/test_tags.rs b/tests/wrapper/test_tags.rs index e51e3a6..5d0580c 100644 --- a/tests/wrapper/test_tags.rs +++ b/tests/wrapper/test_tags.rs @@ -10,7 +10,7 @@ use hydrus_api::wrapper::tag::Tag; async fn retrieve_single_tag(tag: Tag) -> Result<()> { let hydrus = common::get_hydrus(); - hydrus.search(vec![tag]).await?; + hydrus.search().add_tag(tag).run().await?; Ok(()) }