use serde_json::{Map, Value};
use super::spend::Figure;
use super::{fields, spend};
pub(crate) const KIND: &str = "balls";
pub(crate) const HELD: &str = "workspace-balls";
pub(crate) const MARKS: &str = "marks";
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BallRow {
pub ball_id: String,
pub project: String,
pub state: String,
pub title: Option<String>,
pub claimant: Option<String>,
pub workspace: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BoundBall {
pub id: String,
pub badge: Option<String>,
pub project: String,
pub owner: String,
pub state: String,
pub spend: Figure,
}
pub(crate) fn row(value: &Value) -> Result<BallRow, String> {
let obj: &Map<String, Value> = value.as_object().ok_or("balls row: not an object")?;
Ok(BallRow {
ball_id: fields::text(obj, "ball_id")?,
project: fields::text(obj, "project")?,
state: fields::text(obj, "state")?,
title: fields::opt_text(obj, "title")?,
claimant: fields::opt_text(obj, "claimant")?,
workspace: fields::opt_text(obj, "workspace")?,
})
}
pub(crate) fn bound(value: &Value) -> Result<BoundBall, String> {
let obj: &Map<String, Value> = value.as_object().ok_or("ball row: not an object")?;
Ok(BoundBall {
id: fields::text(obj, "id")?,
badge: fields::opt_text(obj, "badge")?,
project: fields::text(obj, "project")?,
owner: fields::text(obj, "owner")?,
state: fields::text(obj, "state")?,
spend: spend::figure(obj.get("spend").ok_or("ball row: missing spend")?)?,
})
}
pub(crate) fn marks(obj: &Map<String, Value>) -> Result<String, String> {
fields::text(obj, "branch")
}
#[cfg(test)]
mod tests;