Skip to main content

mesa_dev/models/
commit.rs

1//! Commit models.
2
3use serde::{Deserialize, Serialize};
4
5use super::lfs::LfsFileRef;
6
7/// A commit author or committer.
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct Author {
10    /// Author name.
11    pub name: String,
12    /// Author email.
13    pub email: String,
14    /// Optional date string.
15    #[serde(skip_serializing_if = "Option::is_none")]
16    pub date: Option<String>,
17}
18
19/// The action to perform on a file in a commit.
20#[derive(Debug, Clone, Serialize)]
21#[serde(rename_all = "lowercase")]
22pub enum CommitFileAction {
23    /// Create or update the file.
24    Upsert,
25    /// Delete the file.
26    Delete,
27}
28
29/// A file change within a commit (legacy struct-based approach).
30#[derive(Debug, Clone, Serialize)]
31pub struct CommitFile {
32    /// The action to perform.
33    pub action: CommitFileAction,
34    /// File path.
35    pub path: String,
36    /// Base64-encoded file content (for upsert).
37    #[serde(skip_serializing_if = "Option::is_none")]
38    pub content: Option<String>,
39}
40
41/// A file change that can be content, delete, or LFS reference.
42///
43/// Use this type for flexibility when you need to mix regular files with LFS files.
44#[derive(Debug, Clone, Serialize)]
45#[serde(untagged)]
46pub enum CommitFileChange {
47    /// Create or update with inline content.
48    Content {
49        /// File path.
50        path: String,
51        /// File content (UTF-8 or base64 encoded).
52        content: String,
53        /// Encoding type.
54        #[serde(skip_serializing_if = "Option::is_none")]
55        encoding: Option<String>,
56    },
57    /// Delete a file.
58    Delete {
59        /// File path.
60        path: String,
61        /// Must be "delete".
62        action: String,
63    },
64    /// Reference an LFS object.
65    Lfs {
66        /// File path.
67        path: String,
68        /// LFS object reference.
69        lfs: LfsFileRef,
70    },
71}
72
73impl CommitFileChange {
74    /// Create an upsert file change with content.
75    pub fn content(path: impl Into<String>, content: impl Into<String>) -> Self {
76        Self::Content {
77            path: path.into(),
78            content: content.into(),
79            encoding: None,
80        }
81    }
82
83    /// Create an upsert file change with base64 content.
84    pub fn content_base64(path: impl Into<String>, content: impl Into<String>) -> Self {
85        Self::Content {
86            path: path.into(),
87            content: content.into(),
88            encoding: Some("base64".to_owned()),
89        }
90    }
91
92    /// Create a delete file change.
93    pub fn delete(path: impl Into<String>) -> Self {
94        Self::Delete {
95            path: path.into(),
96            action: "delete".to_owned(),
97        }
98    }
99
100    /// Create an LFS file reference.
101    pub fn lfs(path: impl Into<String>, oid: impl Into<String>, size: u64) -> Self {
102        Self::Lfs {
103            path: path.into(),
104            lfs: LfsFileRef {
105                oid: oid.into(),
106                size,
107            },
108        }
109    }
110}
111
112/// Request body for creating a commit.
113#[derive(Debug, Clone, Serialize)]
114pub struct CreateCommitRequest {
115    /// Target branch name.
116    pub branch: String,
117    /// Commit message.
118    pub message: String,
119    /// Commit author.
120    pub author: Author,
121    /// Files to include in the commit.
122    pub files: Vec<CommitFile>,
123    /// Optional base SHA for optimistic concurrency.
124    #[serde(skip_serializing_if = "Option::is_none")]
125    pub base_sha: Option<String>,
126}
127
128/// Request body for creating a commit with flexible file types.
129///
130/// Use this when you need to include LFS files in your commit.
131#[derive(Debug, Clone, Serialize)]
132pub struct CreateCommitWithLfsRequest {
133    /// Target branch name.
134    pub branch: String,
135    /// Commit message.
136    pub message: String,
137    /// Commit author.
138    pub author: Author,
139    /// Files to include in the commit.
140    pub files: Vec<CommitFileChange>,
141    /// Optional base SHA for optimistic concurrency.
142    #[serde(skip_serializing_if = "Option::is_none")]
143    pub base_sha: Option<String>,
144}
145
146/// Summary of a commit in a list response.
147#[derive(Debug, Clone, Deserialize)]
148pub struct CommitSummary {
149    /// Commit SHA.
150    pub sha: String,
151    /// Commit message.
152    pub message: String,
153}
154
155/// Full commit details.
156#[derive(Debug, Clone, Deserialize)]
157pub struct Commit {
158    /// Commit SHA.
159    pub sha: String,
160    /// Commit message.
161    pub message: String,
162    /// Commit author.
163    pub author: Author,
164    /// Commit committer.
165    pub committer: Author,
166}
167
168/// Paginated list of commits.
169#[derive(Debug, Clone, Deserialize)]
170pub struct ListCommitsResponse {
171    /// The commits in this page.
172    pub commits: Vec<CommitSummary>,
173    /// Cursor for the next page, if more results exist.
174    pub next_cursor: Option<String>,
175    /// Whether more results are available.
176    pub has_more: bool,
177}