Skip to main content

mesa_dev/client/
commits.rs

1use crate::low_level::apis::{commits_api, Error};
2use crate::low_level::commits;
3use crate::models;
4
5use super::pagination::{paginate, PaginatedResponse};
6use super::RepoClient;
7
8use futures_core::Stream;
9
10impl PaginatedResponse for models::GetByOrgByRepoCommits200Response {
11    type Item = models::GetByOrgByRepoCommits200ResponseCommitsInner;
12
13    fn items(self) -> Vec<Self::Item> {
14        self.commits
15    }
16
17    fn next_cursor(&self) -> Option<&str> {
18        self.next_cursor.as_deref()
19    }
20
21    fn has_more(&self) -> bool {
22        self.has_more
23    }
24}
25
26/// Client for commit operations (`/{org}/{repo}/commits`).
27#[derive(Clone, Debug)]
28pub struct CommitsClient<'a> {
29    pub(super) repo: &'a RepoClient<'a>,
30}
31
32impl<'a> CommitsClient<'a> {
33    /// List commits, optionally filtered by ref.
34    ///
35    /// Returns an async stream that automatically paginates through all results,
36    /// yielding one commit at a time. Pass `limit` to control the page size of
37    /// each underlying API request, or `None` for the server default.
38    pub fn list(
39        &self,
40        r#ref: Option<&'a str>,
41        limit: Option<u8>,
42    ) -> impl Stream<
43        Item = Result<
44            models::GetByOrgByRepoCommits200ResponseCommitsInner,
45            Error<commits_api::GetByOrgByRepoCommitsError>,
46        >,
47    > + 'a {
48        tracing::debug!(
49            org = self.repo.org.org,
50            repo = self.repo.repo,
51            r#ref,
52            limit,
53            "listing commits"
54        );
55        let config = self.repo.org.config;
56        let org = self.repo.org.org;
57        let repo = self.repo.repo;
58
59        paginate(limit, move |cursor, lim| async move {
60            commits_api::get_by_org_by_repo_commits(
61                config,
62                org,
63                repo,
64                cursor.as_deref(),
65                lim,
66                r#ref,
67            )
68            .await
69        })
70    }
71
72    /// Get a specific commit by its SHA.
73    ///
74    /// # Errors
75    ///
76    /// Returns an error if the API request fails.
77    #[tracing::instrument(skip(self), fields(org = self.repo.org.org, repo = self.repo.repo), err(Debug))]
78    pub async fn get(
79        &self,
80        sha: &str,
81    ) -> Result<
82        models::GetByOrgByRepoCommitsBySha200Response,
83        Error<commits_api::GetByOrgByRepoCommitsByShaError>,
84    > {
85        commits_api::get_by_org_by_repo_commits_by_sha(
86            self.repo.org.config,
87            self.repo.org.org,
88            self.repo.repo,
89            Some(sha),
90        )
91        .await
92    }
93
94    /// Create a commit with file operations.
95    ///
96    /// Uses the hand-written implementation to work around the missing
97    /// `Upsert` action variant in the generated code.
98    ///
99    /// # Errors
100    ///
101    /// Returns an error if the API request fails.
102    #[allow(clippy::too_many_arguments)]
103    #[tracing::instrument(skip(self, author, files), fields(org = self.repo.org.org, repo = self.repo.repo), err(Debug))]
104    pub async fn create(
105        &self,
106        branch: &str,
107        message: &str,
108        author: &commits::CommitAuthor,
109        files: &[commits::CommitFile],
110        base_sha: Option<&str>,
111    ) -> Result<commits::CommitResponse, Error<commits::CreateCommitError>> {
112        commits::create_commit(
113            self.repo.org.config,
114            self.repo.org.org,
115            self.repo.repo,
116            branch,
117            message,
118            author,
119            files,
120            base_sha,
121        )
122        .await
123    }
124}