Skip to main content

wme_client/
metadata.rs

1use wme_models::metadata::{Language, Namespace, ProjectInfo, ProjectType};
2use wme_models::RequestParams;
3
4use crate::{ClientError, Result, WmeClient};
5
6/// Metadata API client for discovery endpoints.
7pub struct MetadataClient<'a> {
8    client: &'a WmeClient,
9}
10
11impl<'a> MetadataClient<'a> {
12    /// Create a new metadata client.
13    pub(crate) fn new(client: &'a WmeClient) -> Self {
14        Self { client }
15    }
16
17    /// List all available projects.
18    pub async fn list_projects(&self) -> Result<Vec<ProjectInfo>> {
19        self.list_projects_with_params(None).await
20    }
21
22    /// List projects with filters and field selection.
23    pub async fn list_projects_with_params(
24        &self,
25        params: Option<&RequestParams>,
26    ) -> Result<Vec<ProjectInfo>> {
27        let url = format!("{}/v2/projects", self.client.base_urls().api);
28        let headers = self.client.auth_headers().await?;
29
30        let response = if let Some(p) = params {
31            let body = serde_json::to_string(p)?;
32            self.client
33                .transport()
34                .request(reqwest::Method::POST, &url, headers, Some(body))
35                .await?
36        } else {
37            self.client
38                .transport()
39                .request(reqwest::Method::GET, &url, headers, None)
40                .await?
41        };
42
43        if !response.status().is_success() {
44            return Err(ClientError::Http(format!(
45                "Failed to list projects: {}",
46                response.status()
47            )));
48        }
49
50        let body_text = response.text().await.map_err(ClientError::from)?;
51        let projects: Vec<ProjectInfo> = crate::parse_response(&body_text)?;
52        Ok(projects)
53    }
54
55    /// Get specific project info.
56    pub async fn get_project(&self, identifier: &str) -> Result<ProjectInfo> {
57        self.get_project_with_params(identifier, None).await
58    }
59
60    /// Get project info with field selection.
61    pub async fn get_project_with_params(
62        &self,
63        identifier: &str,
64        params: Option<&RequestParams>,
65    ) -> Result<ProjectInfo> {
66        let url = format!("{}/v2/projects/{}", self.client.base_urls().api, identifier);
67        let headers = self.client.auth_headers().await?;
68
69        let response = if let Some(p) = params {
70            let body = serde_json::to_string(p)?;
71            self.client
72                .transport()
73                .request(reqwest::Method::POST, &url, headers, Some(body))
74                .await?
75        } else {
76            self.client
77                .transport()
78                .request(reqwest::Method::GET, &url, headers, None)
79                .await?
80        };
81
82        if !response.status().is_success() {
83            return Err(ClientError::Http(format!(
84                "Failed to get project: {}",
85                response.status()
86            )));
87        }
88
89        let body_text = response.text().await.map_err(ClientError::from)?;
90        let project: ProjectInfo = crate::parse_response(&body_text)?;
91        Ok(project)
92    }
93
94    /// List all languages.
95    pub async fn list_languages(&self) -> Result<Vec<Language>> {
96        self.list_languages_with_params(None).await
97    }
98
99    /// List languages with filters and field selection.
100    pub async fn list_languages_with_params(
101        &self,
102        params: Option<&RequestParams>,
103    ) -> Result<Vec<Language>> {
104        let url = format!("{}/v2/languages", self.client.base_urls().api);
105        let headers = self.client.auth_headers().await?;
106
107        let response = if let Some(p) = params {
108            let body = serde_json::to_string(p)?;
109            self.client
110                .transport()
111                .request(reqwest::Method::POST, &url, headers, Some(body))
112                .await?
113        } else {
114            self.client
115                .transport()
116                .request(reqwest::Method::GET, &url, headers, None)
117                .await?
118        };
119
120        if !response.status().is_success() {
121            return Err(ClientError::Http(format!(
122                "Failed to list languages: {}",
123                response.status()
124            )));
125        }
126
127        let body_text = response.text().await.map_err(ClientError::from)?;
128        let languages: Vec<Language> = crate::parse_response(&body_text)?;
129        Ok(languages)
130    }
131
132    /// Get specific language info.
133    pub async fn get_language(&self, identifier: &str) -> Result<Language> {
134        self.get_language_with_params(identifier, None).await
135    }
136
137    /// Get language info with field selection.
138    pub async fn get_language_with_params(
139        &self,
140        identifier: &str,
141        params: Option<&RequestParams>,
142    ) -> Result<Language> {
143        let url = format!(
144            "{}/v2/languages/{}",
145            self.client.base_urls().api,
146            identifier
147        );
148        let headers = self.client.auth_headers().await?;
149
150        let response = if let Some(p) = params {
151            let body = serde_json::to_string(p)?;
152            self.client
153                .transport()
154                .request(reqwest::Method::POST, &url, headers, Some(body))
155                .await?
156        } else {
157            self.client
158                .transport()
159                .request(reqwest::Method::GET, &url, headers, None)
160                .await?
161        };
162
163        if !response.status().is_success() {
164            return Err(ClientError::Http(format!(
165                "Failed to get language: {}",
166                response.status()
167            )));
168        }
169
170        let body_text = response.text().await.map_err(ClientError::from)?;
171        let language: Language = crate::parse_response(&body_text)?;
172        Ok(language)
173    }
174
175    /// List all namespaces.
176    pub async fn list_namespaces(&self) -> Result<Vec<Namespace>> {
177        self.list_namespaces_with_params(None).await
178    }
179
180    /// List namespaces with filters and field selection.
181    pub async fn list_namespaces_with_params(
182        &self,
183        params: Option<&RequestParams>,
184    ) -> Result<Vec<Namespace>> {
185        let url = format!("{}/v2/namespaces", self.client.base_urls().api);
186        let headers = self.client.auth_headers().await?;
187
188        let response = if let Some(p) = params {
189            let body = serde_json::to_string(p)?;
190            self.client
191                .transport()
192                .request(reqwest::Method::POST, &url, headers, Some(body))
193                .await?
194        } else {
195            self.client
196                .transport()
197                .request(reqwest::Method::GET, &url, headers, None)
198                .await?
199        };
200
201        if !response.status().is_success() {
202            return Err(ClientError::Http(format!(
203                "Failed to list namespaces: {}",
204                response.status()
205            )));
206        }
207
208        let body_text = response.text().await.map_err(ClientError::from)?;
209        let namespaces: Vec<Namespace> = crate::parse_response(&body_text)?;
210        Ok(namespaces)
211    }
212
213    /// Get specific namespace info.
214    pub async fn get_namespace(&self, identifier: u32) -> Result<Namespace> {
215        self.get_namespace_with_params(identifier, None).await
216    }
217
218    /// Get namespace info with field selection.
219    pub async fn get_namespace_with_params(
220        &self,
221        identifier: u32,
222        params: Option<&RequestParams>,
223    ) -> Result<Namespace> {
224        let url = format!(
225            "{}/v2/namespaces/{}",
226            self.client.base_urls().api,
227            identifier
228        );
229        let headers = self.client.auth_headers().await?;
230
231        let response = if let Some(p) = params {
232            let body = serde_json::to_string(p)?;
233            self.client
234                .transport()
235                .request(reqwest::Method::POST, &url, headers, Some(body))
236                .await?
237        } else {
238            self.client
239                .transport()
240                .request(reqwest::Method::GET, &url, headers, None)
241                .await?
242        };
243
244        if !response.status().is_success() {
245            return Err(ClientError::Http(format!(
246                "Failed to get namespace: {}",
247                response.status()
248            )));
249        }
250
251        let body_text = response.text().await.map_err(ClientError::from)?;
252        let namespace: Namespace = crate::parse_response(&body_text)?;
253        Ok(namespace)
254    }
255
256    /// List project codes.
257    pub async fn list_project_codes(&self) -> Result<Vec<ProjectType>> {
258        self.list_project_codes_with_params(None).await
259    }
260
261    /// List project codes with filters and field selection.
262    pub async fn list_project_codes_with_params(
263        &self,
264        params: Option<&RequestParams>,
265    ) -> Result<Vec<ProjectType>> {
266        let url = format!("{}/v2/codes", self.client.base_urls().api);
267        let headers = self.client.auth_headers().await?;
268
269        let response = if let Some(p) = params {
270            let body = serde_json::to_string(p)?;
271            self.client
272                .transport()
273                .request(reqwest::Method::POST, &url, headers, Some(body))
274                .await?
275        } else {
276            self.client
277                .transport()
278                .request(reqwest::Method::GET, &url, headers, None)
279                .await?
280        };
281
282        if !response.status().is_success() {
283            return Err(ClientError::Http(format!(
284                "Failed to list project codes: {}",
285                response.status()
286            )));
287        }
288
289        let body_text = response.text().await.map_err(ClientError::from)?;
290        let codes: Vec<ProjectType> = crate::parse_response(&body_text)?;
291        Ok(codes)
292    }
293
294    /// Get specific project code info.
295    pub async fn get_project_code(&self, identifier: &str) -> Result<ProjectType> {
296        self.get_project_code_with_params(identifier, None).await
297    }
298
299    /// Get project code info with field selection.
300    pub async fn get_project_code_with_params(
301        &self,
302        identifier: &str,
303        params: Option<&RequestParams>,
304    ) -> Result<ProjectType> {
305        let url = format!("{}/v2/codes/{}", self.client.base_urls().api, identifier);
306        let headers = self.client.auth_headers().await?;
307
308        let response = if let Some(p) = params {
309            let body = serde_json::to_string(p)?;
310            self.client
311                .transport()
312                .request(reqwest::Method::POST, &url, headers, Some(body))
313                .await?
314        } else {
315            self.client
316                .transport()
317                .request(reqwest::Method::GET, &url, headers, None)
318                .await?
319        };
320
321        if !response.status().is_success() {
322            return Err(ClientError::Http(format!(
323                "Failed to get project code: {}",
324                response.status()
325            )));
326        }
327
328        let body_text = response.text().await.map_err(ClientError::from)?;
329        let code: ProjectType = crate::parse_response(&body_text)?;
330        Ok(code)
331    }
332}