hydrus_api/wrapper/
service.rs1use crate::api_core::endpoints::access_management::GetServicesResponse;
2use crate::api_core::endpoints::access_management::{
3 SERVICE_TYPE_ALL_KNOWN_FILES, SERVICE_TYPE_ALL_KNOWN_TAGS, SERVICE_TYPE_ALL_LOCAL_FILES,
4 SERVICE_TYPE_FILE_REPOSITORIES, SERVICE_TYPE_LOCAL_FILES, SERVICE_TYPE_LOCAL_TAGS,
5 SERVICE_TYPE_TAG_REPOSITORIES, SERVICE_TYPE_TRASH,
6};
7
8use crate::api_core::common::ServiceIdentifier;
9use crate::error::Error;
10use crate::wrapper::builders::search_builder::SearchBuilder;
11use crate::Client;
12use std::collections::HashMap;
13use std::convert::TryFrom;
14use std::fmt::{Display, Formatter};
15
16#[derive(Clone, PartialOrd, PartialEq, Hash)]
17pub enum ServiceType {
18 LocalTags,
19 TagRepositories,
20 LocalFiles,
21 FileRepositories,
22 AllLocalFiles,
23 AllKnownFiles,
24 AllKnownTags,
25 Trash,
26}
27
28impl Eq for ServiceType {}
29
30impl TryFrom<String> for ServiceType {
31 type Error = Error;
32
33 fn try_from(value: String) -> Result<Self, Self::Error> {
34 match value.as_str() {
35 s if s == SERVICE_TYPE_LOCAL_TAGS => Ok(Self::LocalTags),
36 s if s == SERVICE_TYPE_TAG_REPOSITORIES => Ok(Self::TagRepositories),
37 s if s == SERVICE_TYPE_LOCAL_FILES => Ok(Self::LocalFiles),
38 s if s == SERVICE_TYPE_FILE_REPOSITORIES => Ok(Self::FileRepositories),
39 s if s == SERVICE_TYPE_ALL_LOCAL_FILES => Ok(Self::AllLocalFiles),
40 s if s == SERVICE_TYPE_ALL_KNOWN_FILES => Ok(Self::AllKnownFiles),
41 s if s == SERVICE_TYPE_ALL_KNOWN_TAGS => Ok(Self::AllKnownTags),
42 s if s == SERVICE_TYPE_TRASH => Ok(Self::Trash),
43 _ => Err(Error::InvalidServiceType(value)),
44 }
45 }
46}
47
48impl ToString for ServiceType {
49 fn to_string(&self) -> String {
50 match self {
51 ServiceType::LocalTags => String::from(SERVICE_TYPE_LOCAL_TAGS),
52 ServiceType::TagRepositories => String::from(SERVICE_TYPE_TAG_REPOSITORIES),
53 ServiceType::LocalFiles => String::from(SERVICE_TYPE_LOCAL_FILES),
54 ServiceType::FileRepositories => String::from(SERVICE_TYPE_FILE_REPOSITORIES),
55 ServiceType::AllLocalFiles => String::from(SERVICE_TYPE_ALL_LOCAL_FILES),
56 ServiceType::AllKnownFiles => String::from(SERVICE_TYPE_ALL_KNOWN_FILES),
57 ServiceType::AllKnownTags => String::from(SERVICE_TYPE_ALL_KNOWN_TAGS),
58 ServiceType::Trash => String::from(SERVICE_TYPE_TRASH),
59 }
60 }
61}
62
63#[derive(Clone, PartialOrd, PartialEq, Hash)]
64pub struct ServiceName(pub String);
65
66impl Eq for ServiceName {}
67
68impl ServiceName {
69 pub fn my_tags() -> Self {
70 Self(String::from("my tags"))
71 }
72
73 pub fn my_files() -> Self {
74 Self(String::from("my files"))
75 }
76
77 pub fn public_tag_repository() -> Self {
78 Self(String::from("public tag repository"))
79 }
80
81 pub fn all_local_files() -> Self {
82 Self(String::from("all local files"))
83 }
84
85 pub fn all_known_tags() -> Self {
86 Self(String::from("all known tags"))
87 }
88
89 pub fn all_known_files() -> Self {
90 Self(String::from("all known files"))
91 }
92}
93
94impl Display for ServiceName {
95 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
96 self.0.fmt(f)
97 }
98}
99
100impl Into<ServiceIdentifier> for ServiceName {
101 fn into(self) -> ServiceIdentifier {
102 ServiceIdentifier::Name(self.0)
103 }
104}
105
106#[derive(Clone)]
107pub struct Service {
108 client: Client,
109 pub name: ServiceName,
110 pub key: String,
111 pub service_type: ServiceType,
112}
113
114impl Service {
115 pub fn search(&self) -> SearchBuilder {
116 let builder = SearchBuilder::new(self.client.clone());
117 match self.service_type {
118 ServiceType::LocalTags | ServiceType::TagRepositories | ServiceType::AllKnownTags => {
119 builder.tag_service_key(&self.key)
120 }
121 ServiceType::LocalFiles
122 | ServiceType::FileRepositories
123 | ServiceType::AllLocalFiles
124 | ServiceType::AllKnownFiles
125 | ServiceType::Trash => builder.file_service_key(&self.key),
126 }
127 }
128}
129
130#[derive(Clone)]
131pub struct Services {
132 inner: HashMap<ServiceType, Vec<Service>>,
133}
134
135impl Services {
136 pub fn from_response(client: Client, response: GetServicesResponse) -> Self {
138 let mut response = response.other;
139 let mut mapped_types = HashMap::with_capacity(response.keys().len());
140 let keys = response.keys().cloned().collect::<Vec<String>>().clone();
141
142 for service_type in &keys {
143 if let Ok(mapped_type) = ServiceType::try_from(service_type.clone()) {
144 let basic_services = response.remove(service_type).unwrap();
145 let mut service_list = Vec::new();
146
147 for basic_service in basic_services {
148 service_list.push(Service {
149 service_type: mapped_type.clone(),
150 name: ServiceName(basic_service.name),
151 key: basic_service.service_key,
152 client: client.clone(),
153 })
154 }
155
156 mapped_types.insert(mapped_type, service_list);
157 }
158 }
159
160 Self {
161 inner: mapped_types,
162 }
163 }
164
165 pub fn get_services(&self, service_type: ServiceType) -> Vec<&Service> {
167 if let Some(services) = self.inner.get(&service_type) {
168 services.into_iter().collect()
169 } else {
170 Vec::new()
171 }
172 }
173}