cranberry 0.1.0

A versatile Rust library for Russian Cyrillic transliteration
Documentation
use crate::alias::{Alphabet, Cyrillic, Latin};

type Processor = fn(&Alphabet, Cyrillic, Option<Cyrillic>, Option<Cyrillic>) -> Latin;

enum Handler {
    Basic,
    Smart(Processor),
}

pub struct Engine {
    alphabet: Alphabet,
    handler: Handler,
}

impl Engine {
    pub fn basic(alphabet: Alphabet) -> Self {
        Self {
            alphabet,
            handler: Handler::Basic,
        }
    }

    pub fn smart(alphabet: Alphabet, processor: Processor) -> Self {
        Self {
            alphabet,
            handler: Handler::Smart(processor),
        }
    }

    pub fn process(&self, source: &str) -> Latin {
        match &self.handler {
            Handler::Basic => self.transliterate(source),
            Handler::Smart(processor) => self.latinize(source, *processor),
        }
    }

    fn transliterate(&self, source: &str) -> Latin {
        source
            .chars()
            .map(|c| {
                self.alphabet
                    .get(&c)
                    .map(|s| s.to_string())
                    .unwrap_or_else(|| c.to_string())
            })
            .collect()
    }

    fn latinize(&self, source: &str, processor: Processor) -> Latin {
        let chars: Vec<Cyrillic> = source.chars().collect();
        let mut result = String::with_capacity(chars.len() * 2);

        for (index, &current) in chars.iter().enumerate() {
            let prev = if index > 0 { Some(chars[index - 1]) } else { None };
            let next = chars.get(index + 1).copied();

            let translated = processor(&self.alphabet, current, prev, next);
            result.push_str(&translated);
        }

        result
    }
}