Skip to main content

smbcloud_model/
project.rs

1use {
2    crate::{app_auth::AuthApp, ar_date_format, runner::Runner},
3    chrono::{DateTime, Utc},
4    serde::{Deserialize, Serialize},
5    serde_repr::{Deserialize_repr, Serialize_repr},
6    std::fmt::Display,
7    tsync::tsync,
8};
9
10/// How the project's files are delivered to the server.
11///
12/// `Git`   — the classic smbCloud flow: push to a remote git repo, the server
13///           builds and restarts the process.
14/// `Rsync` — files are transferred directly with rsync over SSH; no build step
15///           runs on the server. Ideal for pre-built static sites or assets.
16#[derive(Deserialize_repr, Serialize_repr, Debug, Clone, Copy, PartialEq, Eq, Default)]
17#[repr(u8)]
18#[tsync]
19pub enum DeploymentMethod {
20    #[default]
21    Git = 0,
22    Rsync = 1,
23}
24
25impl Display for DeploymentMethod {
26    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27        match self {
28            DeploymentMethod::Git => write!(f, "Git"),
29            DeploymentMethod::Rsync => write!(f, "Rsync"),
30        }
31    }
32}
33
34#[derive(Deserialize, Debug, Serialize)]
35pub struct Config {
36    pub current_project: Option<Project>,
37    pub current_auth_app: Option<AuthApp>,
38}
39
40#[derive(Deserialize, Serialize, Debug, Clone)]
41#[tsync]
42pub struct Project {
43    pub id: i32,
44    pub name: String,
45    pub runner: Runner,
46    /// Defaults to `Git` when absent (older API responses won't include the field).
47    #[serde(default)]
48    pub deployment_method: DeploymentMethod,
49    pub path: Option<String>,
50    pub repository: Option<String>,
51    pub description: Option<String>,
52    pub created_at: DateTime<Utc>,
53    pub updated_at: DateTime<Utc>,
54}
55
56impl Display for Project {
57    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58        write!(f, "ID: {}, Name: {}", self.id, self.name,)
59    }
60}
61#[derive(Serialize, Debug, Deserialize, Clone)]
62#[tsync]
63pub struct ProjectCreate {
64    pub name: String,
65    pub repository: String,
66    pub description: String,
67    pub runner: Runner,
68    #[serde(default)]
69    pub deployment_method: DeploymentMethod,
70}
71
72#[derive(Deserialize, Serialize, Debug)]
73#[tsync]
74pub struct Deployment {
75    pub id: i32,
76    pub project_id: i32,
77    pub commit_hash: String,
78    pub status: DeploymentStatus,
79    #[serde(with = "ar_date_format")]
80    pub created_at: DateTime<Utc>,
81    #[serde(with = "ar_date_format")]
82    pub updated_at: DateTime<Utc>,
83}
84
85#[derive(Deserialize, Serialize, Debug)]
86pub struct DeploymentPayload {
87    pub commit_hash: String,
88    pub status: DeploymentStatus,
89}
90
91#[derive(Deserialize_repr, Serialize_repr, Debug, Clone, Copy)] // Added Clone, Copy
92#[repr(u8)]
93#[tsync]
94pub enum DeploymentStatus {
95    Started = 0,
96    Failed,
97    Done,
98}
99
100impl Display for DeploymentStatus {
101    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
102        match self {
103            DeploymentStatus::Started => write!(f, "🚀"),
104            DeploymentStatus::Failed => write!(f, "❌"),
105            DeploymentStatus::Done => write!(f, "✅"),
106        }
107    }
108}
109
110#[cfg(test)]
111mod tests {
112    use super::*;
113    use serde_json::json;
114    #[test]
115    fn test_project_create() {
116        let project_create = ProjectCreate {
117            name: "test".to_owned(),
118            repository: "test".to_owned(),
119            description: "test".to_owned(),
120            runner: Runner::NodeJs,
121            deployment_method: DeploymentMethod::Git,
122        };
123        let json = json!({
124            "name": "test",
125            "repository": "test",
126            "description": "test",
127            "runner": 0,
128            "deployment_method": 0
129        });
130        assert_eq!(serde_json::to_value(project_create).unwrap(), json);
131    }
132
133    #[test]
134    fn test_deployment_status_display() {
135        assert_eq!(format!("{}", DeploymentStatus::Started), "🚀");
136        assert_eq!(DeploymentStatus::Started.to_string(), "🚀");
137
138        assert_eq!(format!("{}", DeploymentStatus::Failed), "❌");
139        assert_eq!(DeploymentStatus::Failed.to_string(), "❌");
140
141        assert_eq!(format!("{}", DeploymentStatus::Done), "✅");
142        assert_eq!(DeploymentStatus::Done.to_string(), "✅");
143    }
144}