Skip to main content

ratex_parser/mhchem/
data.rs

1//! Load `machines.json` + `patterns_regex.json` and compile regex patterns.
2
3use crate::mhchem::error::{MhchemError, MhchemResult};
4use crate::mhchem::json::Machines;
5use fancy_regex::Regex;
6use std::collections::HashMap;
7use std::sync::OnceLock;
8
9const MACHINES_JSON: &str = include_str!("data/machines.json");
10const PATTERNS_JSON: &str = include_str!("data/patterns_regex.json");
11
12#[derive(Debug)]
13pub struct RegexPatterns {
14    pub map: HashMap<String, Regex>,
15}
16
17#[derive(Debug)]
18pub struct MhchemData {
19    pub machines: Machines,
20    pub regexes: RegexPatterns,
21}
22
23impl MhchemData {
24    pub fn load() -> MhchemResult<Self> {
25        let machines: Machines =
26            serde_json::from_str(MACHINES_JSON).map_err(|e| MhchemError::msg(e.to_string()))?;
27
28        let v: serde_json::Value =
29            serde_json::from_str(PATTERNS_JSON).map_err(|e| MhchemError::msg(e.to_string()))?;
30        let obj = v
31            .get("regex")
32            .and_then(|x| x.as_object())
33            .ok_or_else(|| MhchemError::msg("patterns_regex: missing regex"))?;
34
35        let mut map = HashMap::new();
36        for (k, src_val) in obj {
37            let src = src_val
38                .as_str()
39                .ok_or_else(|| MhchemError::msg("pattern not string"))?;
40            let re = Regex::new(src).map_err(|e| {
41                MhchemError::msg(format!("regex compile {:?}: {}", k, e))
42            })?;
43            map.insert(k.clone(), re);
44        }
45
46        Ok(MhchemData {
47            machines,
48            regexes: RegexPatterns { map },
49        })
50    }
51}
52
53static MHCHEM_DATA: OnceLock<MhchemData> = OnceLock::new();
54
55pub fn data() -> &'static MhchemData {
56    MHCHEM_DATA
57        .get_or_init(|| MhchemData::load().expect("mhchem static data must parse and compile"))
58}