use std::sync::Arc;
use crate::cantonese::{CantoneseScheme, Inventory};
use crate::diagnostics;
use crate::error::{EngineError, Result};
use crate::japanese::JapaneseRomajiScheme;
use crate::korean::KoreanScheme;
use crate::language_dictionary::LanguageDictionary;
use crate::quanpin::QuanpinScheme;
use crate::shuangpin::{ShuangpinProfile, ShuangpinScheme};
use crate::stroke::StrokeScheme;
use crate::tibetan::TibetanScheme;
use crate::types::{QueryRequest, SchemeKey, SchemeType};
use crate::vietnamese::{InputMethod, ToneStyle, VietnameseScheme};
use crate::wubi::scheme::WubiScheme;
use crate::zhuyin::scheme::ZhuyinScheme;
pub enum Scheme {
Quanpin(QuanpinScheme),
Shuangpin(ShuangpinScheme),
Wubi(WubiScheme),
Japanese(JapaneseRomajiScheme),
Korean(KoreanScheme),
Cantonese(CantoneseScheme),
Zhuyin(Box<ZhuyinScheme>),
Vietnamese(VietnameseScheme),
Tibetan(TibetanScheme),
Stroke(StrokeScheme),
}
impl Scheme {
pub fn new(
scheme: SchemeType,
profile: &'static ShuangpinProfile,
vietnamese_method: InputMethod,
vietnamese_style: ToneStyle,
korean_layout: crate::KoreanLayout,
cantonese_inventory: Option<Arc<Inventory>>,
zhuyin_dictionary: Option<LanguageDictionary>,
) -> Result<Self> {
let unavailable = || EngineError::failed(diagnostics::LANGUAGE_DICTIONARY_UNAVAILABLE);
Ok(match scheme {
SchemeType::Quanpin => Self::Quanpin(QuanpinScheme::new()),
SchemeType::Shuangpin => Self::Shuangpin(ShuangpinScheme::new(profile)),
SchemeType::Wubi => Self::Wubi(WubiScheme::new()),
SchemeType::JapaneseRomaji => Self::Japanese(JapaneseRomajiScheme::new()),
SchemeType::Korean => Self::Korean(KoreanScheme::with_layout(korean_layout)),
SchemeType::Cantonese => {
let inventory = cantonese_inventory.ok_or_else(unavailable)?;
Self::Cantonese(CantoneseScheme::new(inventory))
}
SchemeType::Zhuyin => {
let dictionary = zhuyin_dictionary.ok_or_else(unavailable)?;
Self::Zhuyin(Box::new(ZhuyinScheme::new(dictionary)))
}
SchemeType::Vietnamese => {
Self::Vietnamese(VietnameseScheme::new(vietnamese_method, vietnamese_style))
}
SchemeType::Tibetan => Self::Tibetan(TibetanScheme::new()),
SchemeType::Stroke => Self::Stroke(StrokeScheme::new()),
})
}
pub fn scheme_type(&self) -> SchemeType {
match self {
Self::Quanpin(_) => SchemeType::Quanpin,
Self::Shuangpin(_) => SchemeType::Shuangpin,
Self::Wubi(_) => SchemeType::Wubi,
Self::Japanese(_) => SchemeType::JapaneseRomaji,
Self::Korean(_) => SchemeType::Korean,
Self::Cantonese(_) => SchemeType::Cantonese,
Self::Zhuyin(_) => SchemeType::Zhuyin,
Self::Vietnamese(_) => SchemeType::Vietnamese,
Self::Tibetan(_) => SchemeType::Tibetan,
Self::Stroke(_) => SchemeType::Stroke,
}
}
pub fn reset(&mut self) {
match self {
Self::Quanpin(scheme) => scheme.reset(),
Self::Shuangpin(scheme) => scheme.reset(),
Self::Wubi(scheme) => scheme.reset(),
Self::Japanese(scheme) => scheme.reset(),
Self::Korean(scheme) => scheme.reset(),
Self::Cantonese(scheme) => scheme.reset(),
Self::Zhuyin(scheme) => scheme.reset(),
Self::Vietnamese(scheme) => scheme.reset(),
Self::Tibetan(scheme) => scheme.reset(),
Self::Stroke(scheme) => scheme.reset(),
}
}
pub fn handle_key(&mut self, key: SchemeKey) -> bool {
match self {
Self::Quanpin(scheme) => scheme.handle_key(key),
Self::Shuangpin(scheme) => scheme.handle_key(key),
Self::Wubi(scheme) => scheme.handle_key(key),
Self::Japanese(scheme) => scheme.handle_key(key),
Self::Korean(scheme) => scheme.handle_key(key),
Self::Cantonese(scheme) => scheme.handle_key(key),
Self::Zhuyin(_) => false,
Self::Vietnamese(scheme) => scheme.handle_key(key),
Self::Tibetan(scheme) => scheme.handle_key(key),
Self::Stroke(scheme) => scheme.handle_key(key),
}
}
pub fn build_request(&self) -> QueryRequest {
match self {
Self::Quanpin(scheme) => scheme.build_request(),
Self::Shuangpin(scheme) => scheme.build_request(),
Self::Wubi(scheme) => scheme.build_request(),
Self::Japanese(scheme) => scheme.build_request(),
Self::Korean(scheme) => scheme.build_request(),
Self::Cantonese(scheme) => scheme.build_request(),
Self::Zhuyin(scheme) => scheme.build_request(),
Self::Vietnamese(scheme) => scheme.build_request(),
Self::Tibetan(scheme) => scheme.build_request(),
Self::Stroke(scheme) => scheme.build_request(),
}
}
pub fn build_request_into(&self, request: &mut QueryRequest) {
match self {
Self::Quanpin(scheme) => scheme.build_request_into(request),
Self::Shuangpin(scheme) => scheme.build_request_into(request),
Self::Wubi(scheme) => scheme.build_request_into(request),
Self::Japanese(scheme) => scheme.build_request_into(request),
Self::Korean(scheme) => scheme.build_request_into(request),
Self::Cantonese(scheme) => scheme.build_request_into(request),
Self::Zhuyin(scheme) => scheme.build_request_into(request),
Self::Stroke(scheme) => scheme.build_request_into(request),
Self::Vietnamese(scheme) => scheme.build_request_into(request),
Self::Tibetan(scheme) => scheme.build_request_into(request),
}
}
#[allow(dead_code)]
pub fn preedit(&self) -> String {
match self {
Self::Quanpin(scheme) => scheme.preedit(),
Self::Shuangpin(scheme) => scheme.preedit(),
Self::Wubi(scheme) => scheme.preedit(),
Self::Japanese(scheme) => scheme.preedit(),
Self::Korean(scheme) => scheme.preedit(),
Self::Cantonese(scheme) => scheme.preedit(),
Self::Zhuyin(scheme) => scheme.preedit(),
Self::Vietnamese(scheme) => scheme.preedit(),
Self::Tibetan(scheme) => scheme.preedit(),
Self::Stroke(scheme) => scheme.preedit(),
}
}
pub fn set_raw_input(&mut self, raw: &str, raw_with_cases: &str) {
match self {
Self::Quanpin(scheme) => scheme.set_raw_input(raw, raw_with_cases),
Self::Shuangpin(scheme) => scheme.set_raw_input(raw, raw_with_cases),
Self::Wubi(scheme) => scheme.set_raw_input(raw),
Self::Japanese(scheme) => scheme.set_raw_input(raw, raw_with_cases),
Self::Korean(scheme) => scheme.set_raw_input(raw, raw_with_cases),
Self::Cantonese(scheme) => scheme.set_raw_input(raw),
Self::Zhuyin(_) => {}
Self::Vietnamese(scheme) => scheme.set_raw_input(raw, raw_with_cases),
Self::Tibetan(scheme) => scheme.set_raw_input(raw, raw_with_cases),
Self::Stroke(scheme) => scheme.set_raw_input(raw),
}
}
pub fn as_shuangpin_mut(&mut self) -> Option<&mut ShuangpinScheme> {
match self {
Self::Shuangpin(scheme) => Some(scheme),
_ => None,
}
}
pub fn as_wubi_mut(&mut self) -> Option<&mut WubiScheme> {
match self {
Self::Wubi(scheme) => Some(scheme),
_ => None,
}
}
pub fn as_wubi(&self) -> Option<&WubiScheme> {
match self {
Self::Wubi(scheme) => Some(scheme),
_ => None,
}
}
pub fn as_cantonese(&self) -> Option<&CantoneseScheme> {
match self {
Self::Cantonese(scheme) => Some(scheme),
_ => None,
}
}
pub fn as_zhuyin_mut(&mut self) -> Option<&mut ZhuyinScheme> {
match self {
Self::Zhuyin(scheme) => Some(scheme.as_mut()),
_ => None,
}
}
pub fn as_zhuyin(&self) -> Option<&ZhuyinScheme> {
match self {
Self::Zhuyin(scheme) => Some(scheme.as_ref()),
_ => None,
}
}
pub fn into_zhuyin_dictionary(self) -> Option<LanguageDictionary> {
match self {
Self::Zhuyin(scheme) => Some(scheme.into_dictionary()),
_ => None,
}
}
pub fn select_cantonese_end(&mut self, end: usize) -> bool {
let Self::Cantonese(scheme) = self else {
return false;
};
scheme.select_end(end)
}
}