use serde_json::{Map, Value};
use super::fields;
pub(crate) const KIND: &str = "conversations";
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ConvRow {
pub root_id: String,
pub display: String,
pub name: Option<String>,
pub state: AgentState,
pub uncertain: bool,
pub preview: String,
pub age_secs: i64,
pub attention: u64,
pub members: u64,
pub depth: u64,
pub tone: Tone,
pub failure: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum AgentState {
Live,
InFlight,
Quiescent,
Stopped,
Unknown(String),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Tone {
Plain,
Weak,
Good,
Bad,
Live,
InFlight,
Unknown(String),
}
impl AgentState {
pub fn label(&self) -> String {
match self {
Self::Live => "live".to_owned(),
Self::InFlight => IN_FLIGHT.to_owned(),
Self::Quiescent => "quiescent".to_owned(),
Self::Stopped => "stopped".to_owned(),
Self::Unknown(word) => word.clone(),
}
}
pub(crate) fn of(word: &str) -> Self {
match word {
"live" => Self::Live,
IN_FLIGHT => Self::InFlight,
"quiescent" => Self::Quiescent,
"stopped" => Self::Stopped,
other => Self::Unknown(other.to_owned()),
}
}
}
impl Tone {
pub fn label(&self) -> String {
match self {
Self::Plain => "plain".to_owned(),
Self::Weak => "weak".to_owned(),
Self::Good => "good".to_owned(),
Self::Bad => "bad".to_owned(),
Self::Live => "live".to_owned(),
Self::InFlight => IN_FLIGHT.to_owned(),
Self::Unknown(word) => word.clone(),
}
}
fn of(word: &str) -> Self {
match word {
"plain" => Self::Plain,
"weak" => Self::Weak,
"good" => Self::Good,
"bad" => Self::Bad,
"live" => Self::Live,
IN_FLIGHT => Self::InFlight,
other => Self::Unknown(other.to_owned()),
}
}
}
const IN_FLIGHT: &str = "in-flight";
pub(crate) fn row(v: &Value) -> Result<ConvRow, String> {
let o: &Map<String, Value> = v.as_object().ok_or("conversation row: not an object")?;
Ok(ConvRow {
root_id: fields::text(o, "root_id")?,
display: fields::text(o, "display")?,
name: fields::opt_text(o, "name")?,
state: AgentState::of(&fields::text(o, "state")?),
uncertain: fields::flag(o, "uncertain")?,
preview: fields::text(o, "preview")?,
age_secs: fields::secs(o, "age_secs")?,
attention: fields::count(o, "attention")?,
members: fields::count(o, "members")?,
depth: fields::count(o, "depth")?,
tone: Tone::of(&fields::text(o, "tone")?),
failure: fields::opt_text(o, "failure")?,
})
}
#[cfg(test)]
mod tests;