Skip to main content

mesa_dev/resources/
repos.rs

1//! Repository operations.
2//!
3//! Access via [`MesaClient::repos`](crate::MesaClient::repos):
4//!
5//! ```rust,no_run
6//! # use mesa_dev::{Mesa, MesaError, models::CreateRepoRequest};
7//! # async fn run() -> Result<(), MesaError> {
8//! # let client = Mesa::new("key");
9//! let repo = client.repos("my-org").create(&CreateRepoRequest {
10//!     name: "new-repo".to_owned(),
11//!     default_branch: None,
12//! }).await?;
13//! # Ok(())
14//! # }
15//! ```
16
17use std::sync::Arc;
18
19use http::Method;
20
21use crate::client::MesaClient;
22use crate::error::MesaError;
23use crate::http_client::HttpClient;
24use crate::models::{
25    CreateRepoRequest, ListReposResponse, PaginationParams, RenameRepoRequest, Repo,
26    SuccessResponse,
27};
28use crate::pagination::PageStream;
29
30/// Operations on repositories within an organization.
31pub struct ReposResource<'c, C: HttpClient> {
32    client: &'c MesaClient<C>,
33    org: String,
34}
35
36impl<'c, C: HttpClient> ReposResource<'c, C> {
37    pub(crate) fn new(client: &'c MesaClient<C>, org: String) -> Self {
38        Self { client, org }
39    }
40
41    /// Create a new repository.
42    ///
43    /// # Errors
44    ///
45    /// Returns [`MesaError`] if the API request fails.
46    pub async fn create(&self, req: &CreateRepoRequest) -> Result<Repo, MesaError> {
47        let path = format!("/{}/repos", self.org);
48        self.client
49            .request(Method::POST, &path, &[], Some(req))
50            .await
51    }
52
53    /// List repositories with pagination parameters.
54    ///
55    /// # Errors
56    ///
57    /// Returns [`MesaError`] if the API request fails.
58    pub async fn list(&self, params: &PaginationParams) -> Result<ListReposResponse, MesaError> {
59        let path = format!("/{}/repos", self.org);
60        let mut query = Vec::new();
61        if let Some(ref cursor) = params.cursor {
62            query.push(("cursor", cursor.as_str()));
63        }
64        if let Some(limit) = params.limit {
65            let limit_str = limit.to_string();
66            // Need to own the string for the borrow to work.
67            return self
68                .client
69                .request::<ListReposResponse>(
70                    Method::GET,
71                    &path,
72                    &[&query[..], &[("limit", &limit_str)]].concat(),
73                    None::<&()>,
74                )
75                .await;
76        }
77        self.client
78            .request(Method::GET, &path, &query, None::<&()>)
79            .await
80    }
81
82    /// Return a [`PageStream`] that iterates over all repositories.
83    #[must_use]
84    pub fn list_all(&self) -> PageStream<C, ListReposResponse> {
85        let path = format!("/{}/repos", self.org);
86        // TODO(markovejnovic): Do we need Arc here?
87        PageStream::new(Arc::clone(&self.client.inner), path, Vec::new())
88    }
89
90    /// Get a single repository by name.
91    ///
92    /// # Errors
93    ///
94    /// Returns [`MesaError`] if the API request fails.
95    pub async fn get(&self, repo: &str) -> Result<Repo, MesaError> {
96        let path = format!("/{}/{repo}", self.org);
97        self.client
98            .request(Method::GET, &path, &[], None::<&()>)
99            .await
100    }
101
102    /// Rename a repository.
103    ///
104    /// # Errors
105    ///
106    /// Returns [`MesaError`] if the API request fails.
107    pub async fn rename(&self, repo: &str, req: &RenameRepoRequest) -> Result<Repo, MesaError> {
108        let path = format!("/{}/{repo}", self.org);
109        self.client
110            .request(Method::PATCH, &path, &[], Some(req))
111            .await
112    }
113
114    /// Delete a repository.
115    ///
116    /// # Errors
117    ///
118    /// Returns [`MesaError`] if the API request fails.
119    pub async fn delete(&self, repo: &str) -> Result<SuccessResponse, MesaError> {
120        let path = format!("/{}/{repo}", self.org);
121        self.client
122            .request(Method::DELETE, &path, &[], None::<&()>)
123            .await
124    }
125}