use std::path::{Path, PathBuf};
use serde_json::{json, Value};
use super::request::Request;
use super::BackendError;
use crate::shuangpin::profile::{default_profile, profile};
use crate::shuangpin::ShuangpinProfile;
use crate::types::{SchemeType, ShuangpinProfileKind, WordItem, WubiProfileKind};
use crate::RuntimePaths;
#[derive(Clone, Copy)]
pub(super) struct Roots<'a> {
pub(super) resources: &'a Path,
pub(super) dictionaries: &'a Path,
pub(super) scratch: &'a Path,
}
impl Roots<'_> {
fn paths(&self) -> RuntimePaths {
RuntimePaths {
resources: self.resources.to_path_buf(),
user_data: PathBuf::new(),
cache: PathBuf::new(),
dictionaries: self.dictionaries.to_path_buf(),
}
}
pub(super) fn resource(&self, name: &str) -> PathBuf {
self.paths().resource(name)
}
pub(super) fn dictionary(&self, name: &str) -> PathBuf {
self.paths().dictionary(name)
}
pub(super) fn require_resources(&self) -> Result<(), BackendError> {
if self.resources.as_os_str().is_empty() || !self.resources.is_absolute() {
return Err(BackendError::ResourcesUnavailable);
}
Ok(())
}
}
pub(super) fn scheme(request: &Request) -> Result<SchemeType, BackendError> {
match request.string_or("scheme", "pinyin")? {
"pinyin" => Ok(SchemeType::Quanpin),
"shuangpin" => Ok(SchemeType::Shuangpin),
"wubi" | "wubi98" => Ok(SchemeType::Wubi),
_ => Err(BackendError::InvalidRequest),
}
}
pub(super) fn wubi_profile(request: &Request) -> Result<WubiProfileKind, BackendError> {
Ok(match request.string_or("scheme", "pinyin")? {
"wubi98" => WubiProfileKind::Wubi98,
_ => WubiProfileKind::Wubi86,
})
}
pub(super) fn shuangpin_profile(
request: &Request,
) -> Result<&'static ShuangpinProfile, BackendError> {
let name = request.string_or("profile", "xiaohe")?;
Ok(ShuangpinProfileKind::from_name(name)
.and_then(profile)
.unwrap_or_else(default_profile))
}
pub(super) fn candidate(item: &WordItem) -> Value {
json!({
"code": item.pinyin,
"canonical_pinyin": item.canonical_pinyin,
"word": item.word,
"weight": item.weight,
"fixed_position": item.fixed_position,
})
}
pub(super) fn candidates(items: &[WordItem]) -> Value {
json!({ "candidates": items.iter().map(candidate).collect::<Vec<_>>() })
}