readsight 1.0.0

Multilingual readability library — 86 languages, 17 formulas, TeX-based syllable counting via the Frank M. Liang algorithm.
Documentation
//! JSON-backed language repository.

use std::collections::HashMap;

use crate::config::Config;
use crate::error::{Error, Result};

use super::code;
use super::language::Language;

/// Loads and memoizes `Language` definitions from a [`Config`] data source.
pub struct JsonLanguageRepository {
    config: Config,
    cache: HashMap<String, Language>,
}

impl JsonLanguageRepository {
    /// Create a repository backed by the given configuration.
    pub fn new(config: Config) -> Self {
        JsonLanguageRepository {
            config,
            cache: HashMap::new(),
        }
    }

    /// Find (and memoize) a language by code. Returns
    /// [`Error::UnsupportedLanguage`] if no data file exists.
    pub fn find(&mut self, language_code: &str) -> Result<&Language> {
        let normalized = code::normalize(language_code);
        if !self.cache.contains_key(&normalized) {
            let json = self
                .config
                .read_language(&normalized)?
                .ok_or_else(|| Error::UnsupportedLanguage(language_code.to_string()))?;
            let language = Language::from_json(&json)?;
            self.cache.insert(normalized.clone(), language);
        }
        Ok(self.cache.get(&normalized).expect("just inserted"))
    }

    /// All available language codes, sorted ascending.
    pub fn list_codes(&self) -> Result<Vec<String>> {
        self.config.list_language_codes()
    }

    /// Whether a language data file exists for `language_code`.
    pub fn exists(&self, language_code: &str) -> bool {
        let normalized = code::normalize(language_code);
        if self.cache.contains_key(&normalized) {
            return true;
        }
        matches!(self.config.read_language(&normalized), Ok(Some(_)))
    }
}