mesa_dev/resources/commits.rs
1//! Commit operations.
2//!
3//! Access via [`MesaClient::commits`](crate::MesaClient::commits):
4//!
5//! ```rust,no_run
6//! # use mesa_dev::{Mesa, MesaError};
7//! # async fn run() -> Result<(), MesaError> {
8//! # let client = Mesa::new("key");
9//! let commit = client.commits("my-org", "my-repo").get("abc123").await?;
10//! println!("Commit: {}", commit.message);
11//! # Ok(())
12//! # }
13//! ```
14
15use std::sync::Arc;
16
17use http::Method;
18
19use crate::client::MesaClient;
20use crate::error::MesaError;
21use crate::http_client::HttpClient;
22use crate::models::{
23 Commit, CommitSummary, CreateCommitRequest, CreateCommitWithLfsRequest, ListCommitsResponse,
24 PaginationParams,
25};
26use crate::pagination::PageStream;
27
28/// Query parameters for listing commits.
29///
30/// # Example
31///
32/// ```rust
33/// use mesa_dev::resources::ListCommitsParams;
34///
35/// let params = ListCommitsParams {
36/// ref_: Some("main".to_owned()),
37/// ..Default::default()
38/// };
39/// ```
40#[derive(Debug, Clone, Default)]
41pub struct ListCommitsParams {
42 /// Pagination parameters.
43 pub pagination: PaginationParams,
44 /// Optional ref (branch name or SHA) to list commits from.
45 pub ref_: Option<String>,
46}
47
48/// Operations on commits within a repository.
49pub struct CommitsResource<'c, C: HttpClient> {
50 client: &'c MesaClient<C>,
51 org: String,
52 repo: String,
53}
54
55impl<'c, C: HttpClient> CommitsResource<'c, C> {
56 pub(crate) fn new(client: &'c MesaClient<C>, org: String, repo: String) -> Self {
57 Self { client, org, repo }
58 }
59
60 /// Create a new commit.
61 ///
62 /// # Errors
63 ///
64 /// Returns [`MesaError`] if the API request fails.
65 pub async fn create(&self, req: &CreateCommitRequest) -> Result<CommitSummary, MesaError> {
66 let path = format!("/{}/{}/commits", self.org, self.repo);
67 self.client
68 .request(Method::POST, &path, &[], Some(req))
69 .await
70 }
71
72 /// List commits with pagination and optional ref filter.
73 ///
74 /// # Errors
75 ///
76 /// Returns [`MesaError`] if the API request fails.
77 pub async fn list(&self, params: &ListCommitsParams) -> Result<ListCommitsResponse, MesaError> {
78 let path = format!("/{}/{}/commits", self.org, self.repo);
79 let mut query: Vec<(&str, String)> = Vec::new();
80 if let Some(ref cursor) = params.pagination.cursor {
81 query.push(("cursor", cursor.clone()));
82 }
83 if let Some(limit) = params.pagination.limit {
84 query.push(("limit", limit.to_string()));
85 }
86 if let Some(ref r) = params.ref_ {
87 query.push(("ref", r.clone()));
88 }
89 let query_refs: Vec<(&str, &str)> = query.iter().map(|(k, v)| (*k, v.as_str())).collect();
90 self.client
91 .request(Method::GET, &path, &query_refs, None::<&()>)
92 .await
93 }
94
95 /// Return a [`PageStream`] that iterates over all commits.
96 ///
97 /// Optionally filter by ref (branch name or SHA).
98 #[must_use]
99 pub fn list_all(&self, ref_: Option<&str>) -> PageStream<C, ListCommitsResponse> {
100 let path = format!("/{}/{}/commits", self.org, self.repo);
101 let extra = match ref_ {
102 Some(r) => vec![("ref".to_owned(), r.to_owned())],
103 None => Vec::new(),
104 };
105 PageStream::new(Arc::clone(&self.client.inner), path, extra)
106 }
107
108 /// Get a single commit by SHA.
109 ///
110 /// # Errors
111 ///
112 /// Returns [`MesaError`] if the API request fails.
113 pub async fn get(&self, sha: &str) -> Result<Commit, MesaError> {
114 let path = format!("/{}/{}/commits/{sha}", self.org, self.repo);
115 self.client
116 .request(Method::GET, &path, &[], None::<&()>)
117 .await
118 }
119
120 /// Create a new commit with flexible file types (including LFS).
121 ///
122 /// Use this method when you need to include LFS file references in your commit.
123 ///
124 /// # Errors
125 ///
126 /// Returns [`MesaError`] if the API request fails.
127 ///
128 /// # Example
129 ///
130 /// ```rust,no_run
131 /// # use mesa_dev::{Mesa, MesaError};
132 /// # async fn run() -> Result<(), MesaError> {
133 /// # let client = Mesa::new("key");
134 /// use mesa_dev::models::{Author, CommitFileChange, CreateCommitWithLfsRequest};
135 ///
136 /// let commit = client.commits("my-org", "my-repo")
137 /// .create_with_lfs(&CreateCommitWithLfsRequest {
138 /// branch: "main".to_owned(),
139 /// message: "Add large file".to_owned(),
140 /// author: Author {
141 /// name: "Bot".to_owned(),
142 /// email: "bot@example.com".to_owned(),
143 /// date: None,
144 /// },
145 /// files: vec![
146 /// CommitFileChange::lfs("models/large.bin", "abc123...", 12345678),
147 /// ],
148 /// base_sha: None,
149 /// })
150 /// .await?;
151 /// # Ok(())
152 /// # }
153 /// ```
154 pub async fn create_with_lfs(
155 &self,
156 req: &CreateCommitWithLfsRequest,
157 ) -> Result<CommitSummary, MesaError> {
158 let path = format!("/{}/{}/commits", self.org, self.repo);
159 self.client
160 .request(Method::POST, &path, &[], Some(req))
161 .await
162 }
163}