hydrus_api/wrapper/builders/
search_builder.rs1use crate::api_core::endpoints::searching_and_fetching_files::{
2 FileSearchOptions, SearchQueryEntry,
3};
4use crate::error::Result;
5use crate::wrapper::hydrus_file::HydrusFile;
6use crate::wrapper::or_chain::OrChain;
7use crate::wrapper::service::ServiceName;
8use crate::wrapper::tag::Tag;
9use crate::Client;
10
11pub enum SortType {
12 FileSize,
13 Duration,
14 ImportTime,
15 FileType,
16 Random,
17 Width,
18 Height,
19 Ratio,
20 NumberOfPixels,
21 NumberOfTags,
22 NumberOfMediaViewers,
23 MediaViewTime,
24 Bitrate,
25 HasAudio,
26 ModifiedTime,
27 Framerate,
28 NumberOfFrames,
29}
30
31#[derive(Clone, Debug)]
32pub struct SearchBuilder {
33 client: Client,
34 tags: Vec<Tag>,
35 or_chains: Vec<OrChain>,
36 options: FileSearchOptions,
37}
38
39impl SearchBuilder {
40 pub(crate) fn new(client: Client) -> Self {
41 Self {
42 client,
43 tags: Vec::new(),
44 or_chains: Vec::new(),
45 options: FileSearchOptions::new(),
46 }
47 }
48
49 pub fn add_tags(mut self, mut tags: Vec<Tag>) -> Self {
51 self.tags.append(&mut tags);
52 self
53 }
54
55 pub fn add_tag(mut self, tag: Tag) -> Self {
57 self.tags.push(tag);
58 self
59 }
60
61 pub fn add_or_chain(mut self, chain: OrChain) -> Self {
63 self.or_chains.push(chain);
64 self
65 }
66
67 pub fn sort_by(mut self, sort_type: SortType) -> Self {
69 self.options = self.options.sort_type(sort_type as u8);
70 self
71 }
72
73 pub fn sort_descending(mut self) -> Self {
75 self.options = self.options.desc();
76 self
77 }
78
79 pub fn sort_ascending(mut self) -> Self {
81 self.options = self.options.asc();
82 self
83 }
84
85 pub fn file_service_name(mut self, service: ServiceName) -> Self {
87 self.options = self.options.file_service_name(service);
88 self
89 }
90
91 pub fn tag_service_name(mut self, service: ServiceName) -> Self {
93 self.options = self.options.tag_service_name(service);
94 self
95 }
96
97 pub fn file_service_key<S: ToString>(mut self, key: S) -> Self {
100 self.options = self.options.file_service_key(key);
101 self
102 }
103
104 pub fn tag_service_key<S: ToString>(mut self, key: S) -> Self {
107 self.options = self.options.tag_service_key(key);
108 self
109 }
110
111 pub async fn run(self) -> Result<Vec<HydrusFile>> {
113 let client = self.client.clone();
114 let mut entries: Vec<SearchQueryEntry> = self
115 .tags
116 .into_iter()
117 .map(|t| SearchQueryEntry::Tag(t.to_string()))
118 .collect();
119 entries.append(
120 &mut self
121 .or_chains
122 .into_iter()
123 .map(|c| SearchQueryEntry::OrChain(c.into_string_list()))
124 .collect(),
125 );
126 let response = client.search_file_hashes(entries, self.options).await?;
127 let files = response
128 .hashes
129 .into_iter()
130 .map(|hash| HydrusFile::from_hash(client.clone(), hash))
131 .collect();
132
133 Ok(files)
134 }
135}