use crate::classifier::{Recognizer, SegmentType, Verdict};
use serde_json::{Map, Value};
const SPECIFICITY_PATTERN: f64 = 0.3;
pub struct SynthesizedRecognizer {
pub prefix: String,
pub ty: SegmentType,
pub specificity: f64,
}
impl SynthesizedRecognizer {
pub fn from_prefix(prefix: impl Into<String>, ty: SegmentType) -> Self {
SynthesizedRecognizer {
prefix: prefix.into(),
ty,
specificity: SPECIFICITY_PATTERN,
}
}
pub fn from_dump(value: &Value) -> Option<Self> {
let obj = value.as_object()?;
let prefix = obj.get("prefix").and_then(|v| v.as_str())?;
let ty_str = obj.get("type").and_then(|v| v.as_str())?;
let ty = crate::classifier::segment_type_from_str(ty_str)?;
let specificity = obj
.get("specificity")
.and_then(|v| v.as_f64())
.unwrap_or(SPECIFICITY_PATTERN);
Some(SynthesizedRecognizer {
prefix: prefix.to_string(),
ty,
specificity,
})
}
pub fn dump(&self) -> Value {
let mut m = Map::new();
m.insert("prefix".to_string(), Value::String(self.prefix.clone()));
m.insert(
"type".to_string(),
Value::String(self.ty.as_str().to_string()),
);
m.insert(
"specificity".to_string(),
Value::Number(serde_json::Number::from_f64(self.specificity).unwrap()),
);
Value::Object(m)
}
}
impl Recognizer for SynthesizedRecognizer {
fn try_classify(&self, segment: &str) -> Option<Verdict> {
if !segment.starts_with(&self.prefix) {
return None;
}
Some(Verdict {
ty: self.ty,
confidence: 1.0,
specificity: self.specificity,
})
}
}