files_sdk/storage/
projects.rs

1//! Project management operations
2
3use crate::{FilesClient, PaginationInfo, Result};
4use serde::{Deserialize, Serialize};
5use serde_json::json;
6
7/// Represents a project
8#[derive(Debug, Serialize, Deserialize, Clone)]
9pub struct ProjectEntity {
10    pub id: Option<i64>,
11    pub global_access: Option<String>,
12}
13
14#[derive(Debug, Clone)]
15pub struct ProjectHandler {
16    client: FilesClient,
17}
18
19impl ProjectHandler {
20    pub fn new(client: FilesClient) -> Self {
21        Self { client }
22    }
23
24    pub async fn list(
25        &self,
26        cursor: Option<String>,
27        per_page: Option<i64>,
28    ) -> Result<(Vec<ProjectEntity>, PaginationInfo)> {
29        let mut endpoint = "/projects".to_string();
30        let mut params = Vec::new();
31
32        if let Some(c) = cursor {
33            params.push(format!("cursor={}", c));
34        }
35        if let Some(pp) = per_page {
36            params.push(format!("per_page={}", pp));
37        }
38
39        if !params.is_empty() {
40            endpoint.push('?');
41            endpoint.push_str(&params.join("&"));
42        }
43
44        let url = format!("{}{}", self.client.inner.base_url, endpoint);
45        let response = reqwest::Client::new()
46            .get(&url)
47            .header("X-FilesAPI-Key", &self.client.inner.api_key)
48            .send()
49            .await?;
50
51        let headers = response.headers().clone();
52        let pagination = PaginationInfo::from_headers(&headers);
53        let status = response.status();
54
55        if !status.is_success() {
56            return Err(crate::FilesError::ApiError {
57                code: status.as_u16(),
58                message: response.text().await.unwrap_or_default(),
59            });
60        }
61
62        let projects: Vec<ProjectEntity> = response.json().await?;
63        Ok((projects, pagination))
64    }
65
66    pub async fn get(&self, id: i64) -> Result<ProjectEntity> {
67        let endpoint = format!("/projects/{}", id);
68        let response = self.client.get_raw(&endpoint).await?;
69        Ok(serde_json::from_value(response)?)
70    }
71
72    pub async fn create(&self, global_access: &str) -> Result<ProjectEntity> {
73        let body = json!({"global_access": global_access});
74        let response = self.client.post_raw("/projects", body).await?;
75        Ok(serde_json::from_value(response)?)
76    }
77
78    pub async fn update(&self, id: i64, global_access: &str) -> Result<ProjectEntity> {
79        let body = json!({"global_access": global_access});
80        let endpoint = format!("/projects/{}", id);
81        let response = self.client.patch_raw(&endpoint, body).await?;
82        Ok(serde_json::from_value(response)?)
83    }
84
85    pub async fn delete(&self, id: i64) -> Result<()> {
86        let endpoint = format!("/projects/{}", id);
87        self.client.delete_raw(&endpoint).await?;
88        Ok(())
89    }
90}
91
92#[cfg(test)]
93mod tests {
94    use super::*;
95
96    #[test]
97    fn test_handler_creation() {
98        let client = FilesClient::builder().api_key("test-key").build().unwrap();
99        let _handler = ProjectHandler::new(client);
100    }
101}