use serde_json::{Map, Value, json};
use crate::boundary::Action;
use super::start::opt_field;
use super::{obj, opt_str_of, str_of};
pub(super) fn ball(op: &str, project: &str, id: &str, name: &str) -> Value {
json!({ "op": op, "project": project, "id": id, "name": name })
}
pub(super) fn encode_move(project: &str, id: &str, from: &str, to: &str) -> Value {
json!({ "op": "move", "project": project, "id": id, "from": from, "to": to })
}
pub(super) fn create(project: &str, title: &str, name: &str, body: Option<&String>) -> Value {
let mut map = obj(&[("op", "create"), ("title", title), ("name", name)]);
map.insert("project".to_owned(), Value::String(project.to_owned()));
opt_field(&mut map, "body", body);
Value::Object(map)
}
pub(super) fn update(project: &str, id: &str, name: &str, fields: [&Option<String>; 3]) -> Value {
let mut map = obj(&[("op", "update"), ("id", id), ("name", name)]);
map.insert("project".to_owned(), Value::String(project.to_owned()));
for (key, value) in ["title", "body", "note"].into_iter().zip(fields) {
opt_field(&mut map, key, value.as_ref());
}
Value::Object(map)
}
pub(super) fn decode(op: &str, o: &Map<String, Value>) -> Result<Action, String> {
let project = str_of(o, "project")?;
Ok(match op {
"close" => Action::Close {
project,
id: str_of(o, "id")?,
name: str_of(o, "name")?,
},
"assign" => Action::Assign {
project,
id: str_of(o, "id")?,
name: str_of(o, "name")?,
},
"release" => Action::Release {
project,
id: str_of(o, "id")?,
name: str_of(o, "name")?,
},
"move" => Action::Move {
project,
id: str_of(o, "id")?,
from: str_of(o, "from")?,
to: str_of(o, "to")?,
},
"create" => Action::Create {
project,
title: str_of(o, "title")?,
name: str_of(o, "name")?,
body: opt_str_of(o, "body")?,
},
_ => Action::Update {
project,
id: str_of(o, "id")?,
name: str_of(o, "name")?,
title: opt_str_of(o, "title")?,
body: opt_str_of(o, "body")?,
note: opt_str_of(o, "note")?,
},
})
}