duckling 0.4.0

A Rust port of Facebook's Duckling library for parsing natural language into structured data
Documentation
use crate::pattern::regex;
use crate::types::{Rule, TokenData};

use super::OrdinalData;

fn khmer_digit(ch: char) -> Option<i64> {
    match ch {
        '' => Some(0),
        '' => Some(1),
        '' => Some(2),
        '' => Some(3),
        '' => Some(4),
        '' => Some(5),
        '' => Some(6),
        '' => Some(7),
        '' => Some(8),
        '' => Some(9),
        _ => None,
    }
}

fn parse_km_number(s: &str) -> Option<i64> {
    if let Ok(v) = s.parse::<i64>() {
        return Some(v);
    }
    if s.chars().all(|c| khmer_digit(c).is_some()) {
        let mut v = 0i64;
        for ch in s.chars() {
            v = v.checked_mul(10)?.checked_add(khmer_digit(ch)?)?;
        }
        return Some(v);
    }
    match s {
        "មួយ" => Some(1),
        "បួនរយ" => Some(400),
        _ => None,
    }
}

pub fn rules() -> Vec<Rule> {
    vec![Rule {
        name: "ordinal (km ទី...)".to_string(),
        pattern: vec![regex("ទី([០-៩0-9]+|មួយ|បួនរយ)")],
        production: Box::new(|nodes| {
            let s = match &nodes[0].token_data {
                TokenData::RegexMatch(m) => m.group(1)?,
                _ => return None,
            };
            Some(TokenData::Ordinal(OrdinalData::new(parse_km_number(s)?)))
        }),
    }]
}