use serde::Serialize;
use crate::output::Render;
use crate::style::Presentation;
use crate::vocabulary::Role;
use super::copy::{CopyChange, render_value};
use super::toolkit::{Paint, paint};
#[derive(Debug, Clone, Serialize)]
pub struct SetReport {
pub kind: &'static str,
pub name: String,
pub path: String,
pub written: bool,
pub dry_run: bool,
pub pending: Vec<String>,
pub changes: Vec<CopyChange>,
}
impl Render for SetReport {
fn headers() -> &'static [&'static str] {
&["KEY", "CHANGE", "OLD", "NEW"]
}
fn rows(&self) -> Vec<Vec<String>> {
self.changes
.iter()
.map(|change| {
vec![
change.key.clone(),
change.change.to_string(),
change
.old
.as_ref()
.map_or_else(|| "-".to_string(), render_value),
change
.new
.as_ref()
.map_or_else(|| "-".to_string(), render_value),
]
})
.collect()
}
fn rows_for(&self, presentation: Presentation, status_word: bool) -> Vec<Vec<String>> {
let rows = self.rows();
paint(
rows,
Self::headers(),
presentation,
status_word,
|header, cell, _index| match (header, cell) {
("CHANGE", "removed") => Paint::Role(Role::Bark),
("CHANGE", "added") => Paint::Role(Role::Meadow),
_ => Paint::Default,
},
)
}
const PRIORITIES: &'static [u8] = &[0, 0, 6, 7];
}
#[cfg(test)]
mod tests {
use serde_json::json;
use super::super::tests::assert_no_drift;
use super::*;
fn report() -> SetReport {
SetReport {
kind: "sheep",
name: "api".to_string(),
path: "dogs.kelpie.git".to_string(),
written: true,
dry_run: false,
pending: Vec::new(),
changes: vec![
CopyChange {
key: "merging".to_string(),
change: "changed",
old: Some(json!("ff")),
new: Some(json!("rebase")),
},
CopyChange {
key: "remote".to_string(),
change: "added",
old: None,
new: Some(json!("upstream")),
},
],
}
}
#[test]
fn a_set_report_does_not_drift() {
assert_no_drift(&report(), |json| &json["changes"][0], &["OLD", "NEW"]);
}
#[test]
fn a_set_report_renders_one_row_per_change() {
let report = report();
let json = serde_json::to_value(&report).unwrap();
assert_eq!(json["changes"].as_array().unwrap().len(), 2);
assert_eq!(report.rows().len(), 2);
assert_eq!(report.rows()[0], ["merging", "changed", "ff", "rebase"]);
}
#[test]
fn a_set_report_debug_never_prints_a_value() {
let report = SetReport {
kind: "dog",
name: "kelpie".to_string(),
path: "token".to_string(),
written: true,
dry_run: false,
pending: Vec::new(),
changes: vec![CopyChange {
key: "token".to_string(),
change: "changed",
old: Some(json!("hunter2")),
new: Some(json!("rotated")),
}],
};
assert_eq!(
format!("{report:?}"),
"SetReport { kind: \"dog\", name: \"kelpie\", path: \"token\", written: true, \
dry_run: false, pending: [], changes: [CopyChange { key: \"token\", change: \
\"changed\", old: <value>, new: <value> }] }"
);
}
}