use serde_json::{Map, Value, json};
use super::{Attempt, Change, Churn, FileChurn};
use crate::files_view::Preview;
pub(crate) fn reply(attempts: &[Attempt], patch: Option<&Preview>) -> Value {
let mut map = Map::new();
map.insert("ok".to_owned(), json!(true));
map.insert("kind".to_owned(), json!("work-diff"));
map.insert(
"rows".to_owned(),
Value::Array(attempts.iter().map(attempt_row).collect()),
);
if let Some(patch) = patch {
map.insert("patch".to_owned(), preview_value(patch));
}
Value::Object(map)
}
fn attempt_row(attempt: &Attempt) -> Value {
let mut map = Map::new();
map.insert(
"project".to_owned(),
json!(attempt.project.to_string_lossy().into_owned()),
);
map.insert("ball_id".to_owned(), json!(attempt.ball_id));
match &attempt.change {
Change::Unreadable => {
map.insert("state".to_owned(), json!("unreadable"));
}
Change::Absent {
target,
source,
missing,
} => {
map.insert("state".to_owned(), json!("absent"));
map.insert("target".to_owned(), json!(target));
map.insert("source".to_owned(), json!(source));
map.insert("missing".to_owned(), json!(missing));
}
Change::Diff {
target,
source,
target_oid,
source_oid,
files,
truncated,
} => {
map.insert("state".to_owned(), json!("diff"));
map.insert("target".to_owned(), json!(target));
map.insert("source".to_owned(), json!(source));
map.insert("target_oid".to_owned(), json!(target_oid));
map.insert("source_oid".to_owned(), json!(source_oid));
map.insert(
"files".to_owned(),
Value::Array(files.iter().map(file_row).collect()),
);
map.insert("truncated".to_owned(), json!(truncated));
}
}
Value::Object(map)
}
fn file_row(file: &FileChurn) -> Value {
match &file.churn {
Churn::Text { added, removed } => {
json!({ "path": file.path, "added": added, "removed": removed })
}
Churn::Binary => json!({ "path": file.path, "binary": true }),
}
}
fn preview_value(preview: &Preview) -> Value {
match preview {
Preview::Text(text) => json!({ "kind": "text", "text": text }),
Preview::Truncated { text, size } => {
json!({ "kind": "truncated", "text": text, "size": size })
}
Preview::Binary { size } => json!({ "kind": "binary", "size": size }),
}
}