jpreprocess_njd/
node.rs

1use std::fmt::Debug;
2use std::fmt::Display;
3
4use jpreprocess_core::word_entry::WordEntry;
5use jpreprocess_core::{
6    cform::CForm, ctype::CType, pos::*, pronunciation::Pronunciation, word_details::WordDetails,
7};
8
9use jpreprocess_core::accent_rule::ChainRules;
10
11#[derive(Clone, PartialEq, Debug)]
12pub struct NJDNode {
13    string: String, //*は空文字列として扱う
14    details: WordDetails,
15}
16
17impl Display for NJDNode {
18    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19        write!(
20            f,
21            "{},{}",
22            self.string,
23            self.details.to_str_vec(self.string.to_owned()).join(",")
24        )
25    }
26}
27
28impl NJDNode {
29    pub fn new_single(s: &str) -> Self {
30        let nodes = Self::load_csv(s);
31        if nodes.len() == 1 {
32            nodes.into_iter().next().unwrap()
33        } else {
34            panic!("input string must contain exactly one node.");
35        }
36    }
37    pub fn load_csv(s: &str) -> Vec<Self> {
38        let splited = {
39            let mut splited: Vec<&str> = s.split(',').collect();
40            splited.resize(13, "");
41            splited
42        };
43        Self::load_str(splited[0], &splited[1..splited.len()])
44    }
45    pub fn load_str(string: &str, details: &[&str]) -> Vec<Self> {
46        let entry = WordEntry::load(details).unwrap();
47        Self::load(string, &entry)
48    }
49    pub fn load(string: &str, entry: &WordEntry) -> Vec<Self> {
50        entry
51            .get_with_string(string)
52            .into_iter()
53            .map(|(string, details)| Self { string, details })
54            .collect()
55    }
56
57    pub fn transfer_from(&mut self, node: &mut Self) {
58        self.string.push_str(&node.string);
59        if let Some(add) = &node.details.read {
60            if let Some(read) = &mut self.details.read {
61                read.push_str(add);
62            } else {
63                self.details.read = Some(add.to_string());
64            }
65        }
66        self.get_pron_mut().transfer_from(&node.details.pron);
67        node.reset();
68    }
69    pub fn reset(&mut self) {
70        self.string.clear();
71        self.details = WordDetails::default();
72    }
73}
74
75/// Getters and setters
76impl NJDNode {
77    pub fn get_chain_flag(&self) -> Option<bool> {
78        self.details.chain_flag
79    }
80    pub fn set_chain_flag(&mut self, chain_flag: bool) {
81        self.details.chain_flag = Some(chain_flag);
82    }
83
84    pub fn get_chain_rule(&self) -> &ChainRules {
85        &self.details.chain_rule
86    }
87    pub fn unset_chain_rule(&mut self) {
88        self.details.chain_rule.unset();
89    }
90
91    pub fn get_pos(&self) -> &POS {
92        &self.details.pos
93    }
94    pub fn get_pos_mut(&mut self) -> &mut POS {
95        &mut self.details.pos
96    }
97
98    pub fn is_renyou(&self) -> bool {
99        self.details.cform.is_renyou()
100    }
101    pub fn get_ctype(&self) -> &CType {
102        &self.details.ctype
103    }
104    pub fn get_cform(&self) -> &CForm {
105        &self.details.cform
106    }
107
108    pub fn get_string(&self) -> &str {
109        self.string.as_str()
110    }
111    pub fn replace_string(&mut self, new_string: &str) {
112        self.string = new_string.to_string();
113    }
114
115    pub fn get_read(&self) -> Option<&str> {
116        self.details.read.as_deref()
117    }
118    pub fn set_read(&mut self, read: &str) {
119        self.details.read = Some(read.to_string());
120    }
121
122    pub fn get_pron(&self) -> &Pronunciation {
123        &self.details.pron
124    }
125    pub fn get_pron_mut(&mut self) -> &mut Pronunciation {
126        &mut self.details.pron
127    }
128    pub fn set_pron(&mut self, pron: Pronunciation) {
129        self.details.pron = pron;
130    }
131}
132
133#[cfg(test)]
134mod tests {
135    use super::NJDNode;
136
137    #[test]
138    fn single_node() {
139        let node = NJDNode::new_single(".,名詞,接尾,助数詞,*,*,*,.,テン,テン,0/2,*,-1");
140        assert_eq!(node.string, ".");
141        assert!(!node.is_renyou());
142
143        assert_eq!(
144            node.to_string(),
145            ".,名詞,接尾,助数詞,*,*,*,.,テン,テン,0/2,*,-1"
146        )
147    }
148
149    #[test]
150    fn multiple_nodes() {
151        let nodes = NJDNode::load_csv("あーあ,感動詞,*,*,*,*,*,あー:あ,アー:ア,アー:ア,1/2:1/1,C1");
152        assert_eq!(nodes.len(), 2);
153
154        assert_eq!(
155            nodes[0].to_string(),
156            "あー,感動詞,*,*,*,*,*,あー,アー,アー,1/2,C1,-1"
157        );
158        assert_eq!(
159            nodes[1].to_string(),
160            "あ,感動詞,*,*,*,*,*,あ,ア,ア,1/1,C1,0"
161        );
162    }
163
164    #[test]
165    fn test_send() {
166        fn assert_send<T: Send>() {}
167        assert_send::<NJDNode>();
168    }
169
170    #[test]
171    fn test_sync() {
172        fn assert_sync<T: Sync>() {}
173        assert_sync::<NJDNode>();
174    }
175}