hydrus_api/wrapper/builders/
import_builder.rs1use crate::api_core::common::ServiceIdentifier;
2use crate::api_core::endpoints::adding_files::{STATUS_IMPORT_FAILED, STATUS_IMPORT_VETOED};
3use crate::api_core::endpoints::adding_urls::AddUrlRequestBuilder;
4use crate::error::{Error, Result};
5use crate::utils::tag_list_to_string_list;
6use crate::wrapper::hydrus_file::HydrusFile;
7use crate::wrapper::page::PageIdentifier;
8use crate::wrapper::tag::Tag;
9use crate::wrapper::url::Url;
10use crate::Client;
11use std::collections::HashMap;
12use std::io::Read;
13
14pub struct ImportBuilder {
15 pub(crate) client: Client,
16}
17
18impl ImportBuilder {
19 pub fn file(self, file: FileImport) -> FileImportBuilder {
20 FileImportBuilder {
21 client: self.client,
22 file,
23 }
24 }
25
26 pub fn url<S: ToString>(self, url: S) -> UrlImportBuilder {
27 UrlImportBuilder::new(self.client.clone(), url)
28 }
29}
30
31pub enum FileImport {
32 Path(String),
33 Binary(Vec<u8>),
34}
35
36impl FileImport {
37 pub fn path<S: ToString>(path: S) -> Self {
38 Self::Path(path.to_string())
39 }
40
41 pub fn binary<R: Read>(reader: &mut R) -> Self {
42 let mut bytes = Vec::new();
43 let _ = reader.read_to_end(&mut bytes);
44 Self::Binary(bytes)
45 }
46}
47
48pub struct FileImportBuilder {
49 client: Client,
50 file: FileImport,
51}
52
53impl FileImportBuilder {
54 pub async fn run(self) -> Result<HydrusFile> {
55 let response = match self.file {
56 FileImport::Path(path) => self.client.add_file(path).await?,
57 FileImport::Binary(b) => self.client.add_binary_file(b).await?,
58 };
59
60 if response.status == STATUS_IMPORT_FAILED {
61 Err(Error::ImportFailed(response.note))
62 } else if response.status == STATUS_IMPORT_VETOED {
63 Err(Error::ImportVetoed(response.note))
64 } else {
65 Ok(HydrusFile::from_raw_status_and_hash(
66 self.client,
67 response.status,
68 response.hash,
69 ))
70 }
71 }
72}
73
74pub struct UrlImportBuilder {
75 client: Client,
76 url: String,
77 page: Option<PageIdentifier>,
78 show_page: bool,
79 filter_tags: Vec<Tag>,
80 service_tag_mappings: HashMap<ServiceIdentifier, Vec<Tag>>,
81}
82
83impl UrlImportBuilder {
84 pub fn new<S: ToString>(client: Client, url: S) -> Self {
85 Self {
86 client,
87 url: url.to_string(),
88 page: None,
89 show_page: false,
90 filter_tags: vec![],
91 service_tag_mappings: Default::default(),
92 }
93 }
94
95 pub fn page(mut self, page: PageIdentifier) -> Self {
97 self.page = Some(page);
98
99 self
100 }
101
102 pub fn show_page(mut self, show: bool) -> Self {
104 self.show_page = show;
105
106 self
107 }
108
109 pub fn add_filter_tag(mut self, tag: Tag) -> Self {
111 self.filter_tags.push(tag);
112
113 self
114 }
115
116 pub fn add_filter_tags(mut self, mut tags: Vec<Tag>) -> Self {
118 self.filter_tags.append(&mut tags);
119
120 self
121 }
122
123 pub fn add_additional_tag(self, service: ServiceIdentifier, tag: Tag) -> Self {
125 self.add_additional_tags(service, vec![tag])
126 }
127
128 pub fn add_additional_tags(mut self, service: ServiceIdentifier, mut tags: Vec<Tag>) -> Self {
130 if let Some(service_tags) = self.service_tag_mappings.get_mut(&service) {
131 service_tags.append(&mut tags);
132 } else {
133 self.service_tag_mappings.insert(service, tags);
134 }
135
136 self
137 }
138
139 pub async fn run(self) -> Result<Url> {
141 let mut request = AddUrlRequestBuilder::default().url(&self.url);
142
143 for (service, tags) in self.service_tag_mappings {
144 request = request.add_tags(service, tag_list_to_string_list(tags));
145 }
146 request = request.add_filter_tags(tag_list_to_string_list(self.filter_tags));
147 if let Some(page) = self.page {
148 request = match page {
149 PageIdentifier::Name(n) => request.destination_page_name(n),
150 PageIdentifier::Key(k) => request.destination_page_key(k),
151 };
152 }
153 request = request.show_destination_page(self.show_page);
154
155 let response = self.client.add_url(request.build()).await?;
156 let url_info = self.client.get_url_info(&self.url).await?;
157
158 Ok(Url {
159 url: self.url,
160 client: self.client,
161 normalised_url: response.normalised_url,
162 url_type: url_info.url_type.into(),
163 match_name: url_info.match_name,
164 can_parse: url_info.can_parse,
165 })
166 }
167}