use crate::device::device::Connector;
use crate::router_option::RouterOption;
use crate::{ConnectState, FlowState};
use serde::{Deserialize, Serialize};
use std::fmt::{Debug, Formatter};
#[derive(Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct DigitRouter {
pub text: String,
#[serde(rename = "ttsLanguage")]
#[serde(default = "crate::device::shared::build_tts_voice")]
pub tts_voice: String,
#[serde(default = "crate::device::shared::build_finish_key")]
pub finish_on_key: String,
#[serde(default = "crate::device::shared::build_connect_to")]
pub connect_to: String,
#[serde(default)]
pub options: Vec<RouterOption>,
#[serde(default = "crate::device::shared::build_digit_timeout")]
pub timeout: u8,
#[serde(default = "crate::device::shared::build_max_digits")]
pub max_digits: u8,
}
impl DigitRouter {
fn get_opts(&mut self) -> Vec<RouterOption> {
let opts = &mut self.options.clone();
opts.sort_by_key(|o| o.option.chars().count());
opts.reverse();
opts.clone()
}
}
impl Connector for DigitRouter {
fn get_connect_to(&mut self, state: &mut FlowState) -> ConnectState {
match &state.get_digits() {
Some(d) => self
.get_opts()
.iter()
.find(|o| o.option.eq(d.as_str()))
.map(|o| {
ConnectState::matched(
&o.connect_to.to_string(),
Some(d.to_string()),
Some(o.option.clone()),
)
})
.unwrap_or_else(|| {
ConnectState::default(&self.connect_to.to_string(), Some(d.to_string()))
}),
None => ConnectState::default(
&self.connect_to.to_string(),
Some(self.connect_to.to_string()),
),
}
}
}
impl Debug for DigitRouter {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("DigitRouter")
.field("text", &self.text)
.field("tts_voice", &self.tts_voice)
.field("finish_on_key", &self.finish_on_key)
.field("connect_to", &self.connect_to)
.field("options", &self.options)
.field("timeout", &self.timeout)
.field("max_digits", &self.max_digits)
.finish()
}
}