diff --git a/src/display.rs b/src/display.rs new file mode 100644 index 0000000..b88329a --- /dev/null +++ b/src/display.rs @@ -0,0 +1,121 @@ +//! Display forms of Job data. +//! +//! These can be used in tools that wish to display data, such as the `rad-job` +//! CLI tool. + +use radicle::{git::Oid, node::NodeId}; +use serde::Serialize; +use url::Url; +use uuid::Uuid; + +use crate::{JobId, Status}; + +/// A set of [`Job`]s, and how many of them there are, which sorted by their +/// [`JobId`]. +#[derive(Serialize)] +pub struct Jobs { + count: usize, + jobs: Vec, +} + +impl Jobs { + /// Construct the set of [`Jobs`] given an iterator of [`JobId`] and + /// [`Job`][job] pairs. + /// + /// [job]: crate::Job. + pub fn new(jobs: impl Iterator) -> Self { + let mut jobs = jobs.map(|(id, job)| Job::new(id, &job)).collect::>(); + jobs.sort_by_cached_key(|job| job.job_id); + + Self { + count: jobs.len(), + jobs, + } + } + + /// Pretty print the set of [`Jobs`] and their count. + pub fn pretty(&self) -> String { + fn line(s: &mut String, line: String) { + s.push_str(&line); + s.push('\n'); + } + + let mut s = String::new(); + + line(&mut s, format!("count: {}", self.count)); + for shown in self.jobs.iter() { + line( + &mut s, + format!("job {} (commit {})", shown.job_id, shown.oid), + ); + for run in shown.runs.iter() { + line(&mut s, format!(" node {}", run.node_id)); + for run2 in run.runs.iter() { + line(&mut s, format!(" run {} {:?}", run2.run_id, run2.status)); + line(&mut s, format!(" log {}", run2.log)); + } + } + s.push('\n'); + } + + s + } +} + +/// A display form of a [`Job`][job]. +/// +/// [job]: crate::Job. +#[derive(Serialize)] +pub struct Job { + job_id: JobId, + oid: Oid, + runs: Vec, +} + +impl Job { + /// Construct a new [`Job`] given the [`JobId`] and collaborative object + /// form of the [`Job`][job]. + /// + /// [job]: crate::Job. + pub fn new(job_id: JobId, job: &crate::Job) -> Self { + let mut runs: Vec<_> = job + .runs() + .iter() + .map(|(node_id, runs)| { + let mut runs: Vec = runs + .iter() + .map(|(run_id, run)| Run { + run_id: *run_id, + status: *run.status(), + log: run.log().clone(), + }) + .collect(); + runs.sort_by_cached_key(|run| run.run_id); + Runs { + node_id: *node_id, + runs, + } + }) + .collect(); + runs.sort_by_cached_key(|run| run.node_id); + + Self { + job_id, + oid: *job.oid(), + runs, + } + } +} + +#[derive(Serialize)] +struct Runs { + node_id: NodeId, + runs: Vec, +} + +#[derive(Serialize)] +struct Run { + run_id: Uuid, + status: Status, + log: Url, +} diff --git a/src/lib.rs b/src/lib.rs index 6474014..153e242 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -69,6 +69,7 @@ use serde::{Deserialize, Serialize}; use url::Url; use uuid::Uuid; +pub mod display; pub mod error; /// Type name of a patch.