jpreprocess_jpcommon/label/
utterance.rs1use jpreprocess_njd::NJDNode;
2
3use crate::limit::Limit;
4
5use super::*;
6
7#[derive(Clone, Debug)]
8pub struct Utterance {
9 pub breath_groups: Vec<BreathGroup>,
10}
11
12impl Utterance {
13 pub fn to_k(&self) -> jlabel::Utterance {
14 jlabel::Utterance {
15 breath_group_count: Limit::S.ulimit(self.breath_groups.len()),
16 accent_phrase_count: Limit::M.ulimit(self.count_accent_phrase()),
17 mora_count: Limit::LL.ulimit(self.count_mora()),
18 }
19 }
20
21 pub fn count_accent_phrase(&self) -> usize {
22 self.breath_groups
23 .iter()
24 .map(|bg| bg.count_accent_phrase())
25 .sum()
26 }
27 pub fn count_mora(&self) -> usize {
28 self.breath_groups.iter().map(|bg| bg.count_mora()).sum()
29 }
30}
31
32impl From<&[NJDNode]> for Utterance {
33 fn from(nodes: &[NJDNode]) -> Self {
34 let mut breath_groups: Vec<BreathGroup> = Vec::new();
35 let mut accent_phrases: Vec<AccentPhrase> = Vec::with_capacity(nodes.len());
36
37 for node in nodes {
38 if node.get_pron().is_question() {
39 if let Some(accent_phrase) = accent_phrases.last_mut() {
40 accent_phrase.set_interrogative();
41 } else {
42 eprintln!("WARN: First mora should not be question flag.");
43 }
44 }
45 if node.get_pron().is_touten() || node.get_pron().is_question() {
46 if !accent_phrases.is_empty() {
47 breath_groups.push(BreathGroup::new(accent_phrases));
48 }
49 accent_phrases = Vec::new();
50 continue;
51 }
52
53 if matches!(node.get_chain_flag(), Some(true)) {
54 if let Some(accent_phrase) = accent_phrases.last_mut() {
55 accent_phrase.push_node(node);
56 } else {
57 accent_phrases.push(AccentPhrase::new(node));
58 eprintln!("WARN: First mora cannot be chained.");
59 }
60 } else {
61 accent_phrases.push(AccentPhrase::new(node));
62 }
63 }
64 if !accent_phrases.is_empty() {
65 breath_groups.push(BreathGroup::new(accent_phrases));
66 }
67
68 Self { breath_groups }
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use crate::Utterance;
75
76 #[test]
77 fn test_send() {
78 fn assert_send<T: Send>() {}
79 assert_send::<Utterance>();
80 }
81
82 #[test]
83 fn test_sync() {
84 fn assert_sync<T: Sync>() {}
85 assert_sync::<Utterance>();
86 }
87}