use crate::Error;
use std::borrow::Cow;
use std::collections::HashMap;
#[must_use]
pub fn strip_accents(text: &str) -> Cow<'_, str> {
crate::transliterate::strip_accents_cow(text)
}
#[must_use]
pub fn is_ascii(text: &str) -> bool {
text.is_ascii()
}
#[must_use]
pub fn list_langs() -> Vec<String> {
crate::tables::list_langs()
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
#[non_exhaustive]
pub enum Scheme {
#[default]
Default,
StrictIso9,
GostR7034,
}
impl Scheme {
fn flags(self) -> (bool, bool) {
match self {
Scheme::Default => (false, false),
Scheme::StrictIso9 => (true, false),
Scheme::GostR7034 => (false, true),
}
}
#[must_use]
pub fn as_str(self) -> &'static str {
match self {
Scheme::Default => "default",
Scheme::StrictIso9 => "strict_iso9",
Scheme::GostR7034 => "gost7034",
}
}
}
impl std::fmt::Display for Scheme {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
impl std::str::FromStr for Scheme {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"default" => Ok(Self::Default),
"strict_iso9" => Ok(Self::StrictIso9),
"gost7034" => Ok(Self::GostR7034),
_ => Err(Error::from(crate::ErrorRepr::InvalidScheme {
got: s.to_owned(),
})),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum OnUnknown {
Replace(String),
Ignore,
Preserve,
}
impl Default for OnUnknown {
fn default() -> Self {
OnUnknown::Replace("[?]".to_owned())
}
}
impl OnUnknown {
fn parts(&self) -> (crate::ErrorMode, &str) {
match self {
OnUnknown::Replace(s) => (crate::ErrorMode::Replace, s.as_str()),
OnUnknown::Ignore => (crate::ErrorMode::Ignore, ""),
OnUnknown::Preserve => (crate::ErrorMode::Preserve, ""),
}
}
}
#[derive(Debug, Clone, Default)]
pub struct Transliterate {
lang: Option<String>,
scheme: Scheme,
on_unknown: Option<OnUnknown>,
tones: bool,
}
impl Transliterate {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn lang(mut self, lang: impl Into<String>) -> Self {
self.lang = Some(lang.into());
self
}
#[must_use]
pub fn scheme(mut self, scheme: Scheme) -> Self {
self.scheme = scheme;
self
}
#[must_use]
pub fn on_unknown(mut self, on_unknown: OnUnknown) -> Self {
self.on_unknown = Some(on_unknown);
self
}
#[must_use]
pub fn tones(mut self, tones: bool) -> Self {
self.tones = tones;
self
}
#[must_use]
pub fn run<'a>(&self, text: &'a str) -> Cow<'a, str> {
let (error_mode, replacement) = match &self.on_unknown {
None => (crate::ErrorMode::Replace, "[?]"),
Some(on_unknown) => on_unknown.parts(),
};
let (strict_iso9, gost7034) = self.scheme.flags();
crate::transliterate::transliterate_impl(
text,
self.lang.as_deref(),
error_mode,
replacement,
strict_iso9,
gost7034,
self.tones,
)
}
#[must_use]
pub fn find_untranslatable(&self, text: &str) -> Vec<Untranslatable> {
let (strict_iso9, gost7034) = self.scheme.flags();
crate::transliterate::find_untranslatable_impl(
text,
self.lang.as_deref(),
strict_iso9,
gost7034,
self.tones,
)
.into_iter()
.map(|(ch, offset)| Untranslatable { ch, offset })
.collect()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub struct Untranslatable {
pub ch: char,
pub offset: usize,
}
#[must_use]
pub fn transliterate(text: &str) -> Cow<'_, str> {
Transliterate::new().run(text)
}
pub fn register_lang(code: &str, mappings: HashMap<String, String>) -> Result<(), Error> {
crate::transliterate::register_lang(code, mappings).map_err(Error::from)
}
pub fn register_replacements(replacements: HashMap<String, String>) -> Result<(), Error> {
crate::transliterate::register_replacements(replacements).map_err(Error::from)
}
pub fn remove_replacement(key: &str) -> Result<bool, Error> {
crate::transliterate::remove_replacement(key).map_err(Error::from)
}
pub fn clear_replacements() -> Result<(), Error> {
crate::transliterate::clear_replacements().map_err(Error::from)
}
pub fn seal_registrations() {
crate::tables::seal_registrations();
}
#[must_use]
pub fn registrations_sealed() -> bool {
crate::tables::registrations_sealed()
}