use serde::Deserialize;
use crate::error::{Error, Result};
const EN_CORE_WEB_SM: &str = include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/assets/spacy_en/tokenizer.json"
));
pub(crate) type SpecialPiece = (String, Option<String>);
#[derive(Debug, Deserialize)]
pub(crate) struct TokenizerData {
pub source: String,
pub faster_heuristics: bool,
pub prefix: Option<String>,
pub suffix: Option<String>,
pub infix: Option<String>,
pub token_match: Option<String>,
pub url_match: Option<String>,
pub rules: Vec<(String, Vec<SpecialPiece>)>,
pub base_norms: Vec<(String, String)>,
pub lexeme_norm: Vec<(u64, String)>,
}
impl TokenizerData {
pub(crate) fn en_core_web_sm() -> Result<Self> {
serde_json::from_str(EN_CORE_WEB_SM).map_err(|e| Error::ModelError {
reason: format!("assets/spacy_en/tokenizer.json does not parse: {e}"),
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn embedded_data_parses() {
let data = TokenizerData::en_core_web_sm()
.unwrap_or_else(|e| panic!("embedded tokenizer data: {e}"));
assert!(data.source.contains("en_core_web_sm 3.8.0"));
assert!(data.faster_heuristics);
assert!(data.prefix.is_some() && data.suffix.is_some() && data.infix.is_some());
assert!(data.token_match.is_none() && data.url_match.is_some());
assert!(data.rules.iter().any(|(chunk, _)| chunk == "don't"));
assert!(!data.base_norms.is_empty() && !data.lexeme_norm.is_empty());
}
}