use std::collections::HashMap;
use crate::model::{Flow, Node, Prompt};
pub type NodeId = String;
impl Node {
pub fn kind(&self) -> &'static str {
match self {
Node::Greeting { .. } => "greeting",
Node::Hours { .. } => "hours",
Node::Menu { .. } => "menu",
Node::Ring { .. } => "ring",
Node::Message { .. } => "message",
Node::Transfer { .. } => "transfer",
Node::Hangup { .. } => "hangup",
}
}
pub fn is_terminal(&self) -> bool {
matches!(
self,
Node::Message { .. } | Node::Transfer { .. } | Node::Hangup { .. } | Node::Ring { .. }
)
}
pub fn required_exits(&self) -> Vec<String> {
match self {
Node::Greeting { .. } => vec!["next".into()],
Node::Hours { .. } => vec!["open".into(), "closed".into()],
Node::Menu { options, .. } => {
let mut names: Vec<String> = options.keys().cloned().collect();
names.push("no_input".into());
names.push("invalid".into());
names
}
Node::Ring { .. } => vec!["no_answer".into()],
Node::Message { .. } | Node::Transfer { .. } | Node::Hangup { .. } => Vec::new(),
}
}
pub fn exits(&self) -> Option<&HashMap<String, String>> {
let exits = match self {
Node::Greeting { exits, .. }
| Node::Hours { exits, .. }
| Node::Menu { exits, .. }
| Node::Ring { exits, .. }
| Node::Message { exits, .. }
| Node::Transfer { exits, .. }
| Node::Hangup { exits, .. } => exits,
};
exits.as_deref()
}
}
impl Prompt {
pub fn as_text(&self) -> Option<&str> {
match self {
Prompt::Text(t) => Some(t.as_str()),
Prompt::Audio { .. } => None,
}
}
}
impl Flow {
pub fn from_yaml(src: &str) -> Result<Flow, serde_yaml_ng::Error> {
let value: serde_yaml_ng::Value = serde_yaml_ng::from_str(src)?;
serde_yaml_ng::from_value(value)
}
pub fn to_yaml(&self) -> Result<String, serde_yaml_ng::Error> {
serde_yaml_ng::to_string(self)
}
}