use std::fmt;
use serde::{Deserialize, Serialize};
use radicle::git::Oid;
use radicle::prelude::RepoId;
use radicle_job::JobId;
use crate::msg::{Revision, RunId, RunResult};
#[derive(Debug, Default)]
pub struct RunBuilder {
broker_run_id: Option<RunId>,
repo_id: Option<RepoId>,
repo_name: Option<String>,
whence: Option<Whence>,
timestamp: Option<String>,
}
impl RunBuilder {
pub fn broker_run_id(mut self, run_id: RunId) -> Self {
self.broker_run_id = Some(run_id);
self
}
pub fn repo_id(mut self, repo_id: RepoId) -> Self {
self.repo_id = Some(repo_id);
self
}
pub fn repo_name(mut self, name: &str) -> Self {
self.repo_name = Some(name.into());
self
}
pub fn whence(mut self, whence: Whence) -> Self {
self.whence = Some(whence);
self
}
pub fn timestamp(mut self, ts: String) -> Self {
self.timestamp = Some(ts);
self
}
pub fn build(self) -> Run {
let broker_run_id = self
.broker_run_id
.unwrap_or_else(|| panic!("missing: broker_run_id"));
let repo_id = self.repo_id.unwrap_or_else(|| panic!("missing: repo_id"));
let repo_name = self
.repo_name
.unwrap_or_else(|| panic!("missing: repo_name"));
let whence = self.whence.unwrap_or_else(|| panic!("missing: whence"));
let timestamp = self
.timestamp
.unwrap_or_else(|| panic!("missing: timestamp"));
Run {
broker_run_id,
adapter_run_id: None,
adapter_info_url: None,
job_id: None,
repo_id,
repo_name,
timestamp,
whence,
state: RunState::Triggered,
result: None,
timed_out: None,
}
}
}
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct Run {
broker_run_id: RunId,
adapter_run_id: Option<RunId>,
adapter_info_url: Option<String>,
repo_id: RepoId,
#[serde(alias = "repo_alias")]
repo_name: String,
timestamp: String,
whence: Whence,
state: RunState,
result: Option<RunResult>,
job_id: Option<JobId>,
timed_out: Option<bool>,
}
impl Run {
pub fn set_job_id(&mut self, job_id: JobId) {
self.job_id = Some(job_id);
}
pub fn job_id(&self) -> Option<JobId> {
self.job_id
}
pub fn repo_alias(&self) -> &str {
&self.repo_name
}
pub fn repo_id(&self) -> RepoId {
self.repo_id
}
pub fn timestamp(&self) -> &str {
&self.timestamp
}
pub fn whence(&self) -> &Whence {
&self.whence
}
pub fn broker_run_id(&self) -> &RunId {
&self.broker_run_id
}
pub fn set_adapter_run_id(&mut self, run_id: RunId) {
assert!(self.adapter_run_id.is_none());
self.adapter_run_id = Some(run_id);
}
pub fn adapter_run_id(&self) -> Option<&RunId> {
self.adapter_run_id.as_ref()
}
pub fn set_adapter_info_url(&mut self, info_url: &str) {
self.adapter_info_url = Some(info_url.into());
}
pub fn adapter_info_url(&self) -> Option<&str> {
self.adapter_info_url.as_deref()
}
pub fn state(&self) -> RunState {
self.state
}
pub fn set_state(&mut self, state: RunState) {
self.state = state;
}
pub fn set_result(&mut self, result: RunResult) {
self.result = Some(result);
}
pub fn unset_result(&mut self) {
self.result = None;
}
pub fn result(&self) -> Option<&RunResult> {
self.result.as_ref()
}
pub fn set_timed_out(&mut self) {
self.timed_out = Some(true);
}
pub fn timed_out(&self) -> bool {
self.timed_out == Some(true)
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum RunState {
Triggered,
Running,
Finished,
}
impl fmt::Display for RunState {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
let s = match self {
Self::Finished => "finished",
Self::Running => "running",
Self::Triggered => "triggered",
};
write!(f, "{s}")
}
}
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub enum Whence {
Branch {
name: String,
commit: Oid,
who: Option<String>,
},
Patch {
patch: Oid,
commit: Oid,
revision: Option<Revision>,
who: Option<String>,
},
}
impl Whence {
pub fn branch(name: &str, commit: Oid, who: Option<&str>) -> Self {
Self::Branch {
name: name.into(),
commit,
who: who.map(|s| s.to_string()),
}
}
pub fn patch(patch: Oid, commit: Oid, revision: Revision, who: Option<&str>) -> Self {
Self::Patch {
patch,
commit,
revision: Some(revision),
who: who.map(|s| s.to_string()),
}
}
}
impl Whence {
pub fn oid(&self) -> Oid {
match self {
Self::Branch { commit, .. } => *commit,
Self::Patch { commit, .. } => *commit,
}
}
pub fn who(&self) -> Option<&str> {
match self {
Self::Branch {
name: _,
commit: _,
who,
} => who.as_ref().map(|x| x.as_str()),
Self::Patch {
patch: _,
commit: _,
revision: _,
who,
} => who.as_ref().map(|x| x.as_str()),
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn serialize_run_state() -> Result<(), Box<dyn std::error::Error>> {
let s = serde_json::to_string(&RunState::Finished)?;
assert_eq!(s, r#""finished""#);
Ok(())
}
}