use std::borrow::Borrow;
use std::sync::Arc;
use super::rule::AfxRule;
use crate::morph::MorphInfo;
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Meta {
stem: Arc<str>,
source: Source,
}
impl Meta {
pub(crate) fn new(stem_rc: Arc<str>, source: Source) -> Self {
Self {
stem: stem_rc,
source,
}
}
pub fn stem(&self) -> &str {
if let Source::Dict(morphvec) = &self.source {
if let Some(stem) = morphvec.iter().find_map(|morph| {
if let MorphInfo::Stem(st) = morph.borrow() {
Some(st)
} else {
None
}
}) {
return stem.as_ref();
}
}
&self.stem
}
pub fn source(&self) -> &Source {
&self.source
}
}
#[allow(clippy::box_collection)]
#[non_exhaustive]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum Source {
Affix {
rule: Arc<AfxRule>,
pat_idx: usize,
},
Dict(Arc<[Arc<MorphInfo>]>),
Personal(Arc<PersonalMeta>),
Raw,
}
impl Source {
pub fn morphs(&self) -> impl Iterator<Item = &MorphInfo> {
match self {
Source::Affix { rule, pat_idx } => rule.patterns()[*pat_idx].morph_info(),
Source::Dict(v) => v.as_ref(),
Source::Personal(v) => v.morph.as_ref(),
Source::Raw => &[],
}
.iter()
.map(AsRef::as_ref)
}
pub(crate) fn new_affix(rule: &Arc<AfxRule>, pat_idx: usize) -> Self {
Self::Affix {
rule: Arc::clone(rule),
pat_idx,
}
}
}
#[derive(Debug, PartialEq, Eq, Hash)]
pub struct PersonalMeta {
friend: Option<Arc<str>>,
morph: Vec<Arc<MorphInfo>>,
}
impl PersonalMeta {
pub fn new(friend: Option<Arc<str>>, morph: Vec<Arc<MorphInfo>>) -> Self {
Self { friend, morph }
}
}
#[cfg(test)]
#[allow(unused)]
mod tests {
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
use super::*;
fn calculate_hash<T: Hash>(t: &T) -> u64 {
let mut s = DefaultHasher::new();
t.hash(&mut s);
s.finish()
}
}