use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", content = "data")]
pub enum PluginEvent {
Startup,
IssueCreated { issue_id: String },
IssueUpdated { issue_id: String },
IssueStatusChanged {
issue_id: String,
old_status: String,
new_status: String,
},
CommitCreated { commit_hash: String },
BranchCreated { branch_id: String },
BranchUpdated { branch_id: String },
AgentAction { action: String, branch_id: String },
PipelineStatusQuery {
mr_id: String,
project_id: String,
source_branch: String,
target_branch: String,
forge_type: String,
api_url: String,
},
Custom {
name: String,
payload: serde_json::Value,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PipelineStatus {
pub status: PipelineState,
pub pipeline_id: Option<String>,
pub jobs: Vec<PipelineJob>,
pub updated_at: Option<String>,
pub web_url: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum PipelineState {
Passed,
Failed,
Running,
Pending,
Canceled,
Skipped,
Unknown,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PipelineJob {
pub name: String,
pub status: PipelineState,
pub duration: Option<String>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn event_round_trips_through_json() {
let evt = PluginEvent::IssueStatusChanged {
issue_id: "abc".into(),
old_status: "todo".into(),
new_status: "done".into(),
};
let s = serde_json::to_string(&evt).unwrap();
assert!(s.contains(r#""type":"IssueStatusChanged""#));
let back: PluginEvent = serde_json::from_str(&s).unwrap();
match back {
PluginEvent::IssueStatusChanged { new_status, .. } => assert_eq!(new_status, "done"),
_ => panic!("variant lost in round-trip"),
}
}
#[test]
fn pipeline_state_lowercases() {
let s = serde_json::to_string(&PipelineState::Passed).unwrap();
assert_eq!(s, "\"passed\"");
}
}