hydrus_api/wrapper/
service.rs

1use 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    /// Creates the services list from a given hydrus response
137    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    /// Returns a list of all services of the given type
166    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}