1use std::collections::BTreeMap;
2use std::fmt;
3
4#[derive(Debug)]
5pub struct Record {
6 pub english: String,
7 pub michuhu: String,
8}
9
10#[derive(Debug)]
11pub enum Answer {
12 One(String),
13 Many(Vec<String>),
14}
15
16impl Answer {
17 pub fn join(&mut self, b: Self) {
18 let mut t = Answer::One(String::new());
19 std::mem::swap(&mut t, self);
20 use Answer::*;
21 *self = match (t, b) {
22 (One(o), Many(mut m)) | (Many(mut m), One(o)) => {
23 if !m.contains(&o) {
24 m.push(o);
25 }
26 Many(m)
27 }
28 (Many(mut ma), Many(mb)) => {
29 for o in mb {
30 if !ma.contains(&o) {
31 ma.push(o);
32 }
33 }
34 Many(ma)
35 }
36 (One(a), One(b)) => {
37 if a == b {
38 One(a)
39 } else {
40 Many(vec![a, b])
41 }
42 }
43 }
44 }
45}
46
47impl fmt::Display for Answer {
48 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
49 match self {
50 Answer::One(s) => write!(f, "{}", s),
51 Answer::Many(v) => {
52 let mut coma = "";
53 for x in v {
54 write!(f, "{}{}", x, coma)?;
55 coma = " , "
56 }
57 Ok(())
58 }
59 }
60 }
61}
62
63#[derive(Debug)]
64pub struct AnsMap {
65 pub mp: BTreeMap<String, Answer>,
66}
67
68impl AnsMap {
69 pub fn new() -> Self {
70 AnsMap {
71 mp: BTreeMap::new(),
72 }
73 }
74
75 pub fn insert_s(&mut self, k: String, v: String) {
76 self.insert(k, Answer::One(v))
77 }
78
79 pub fn insert(&mut self, k: String, v: Answer) {
80 if let Some(gm) = self.mp.get_mut(&k) {
81 gm.join(v)
82 } else {
83 self.mp.insert(k, v);
84 }
85 }
86}
87
88#[derive(Debug)]
89pub struct TwoWayMap {
90 pub e_m: AnsMap,
91 pub m_e: AnsMap,
92}
93
94impl TwoWayMap {
95 pub fn new() -> Self {
96 TwoWayMap {
97 e_m: AnsMap::new(),
98 m_e: AnsMap::new(),
99 }
100 }
101 pub fn insert(&mut self, r: Record) {
102 self.e_m.insert_s(r.english.clone(), r.michuhu.clone());
103 self.m_e.insert_s(r.michuhu, r.english);
104 }
105
106 pub fn merge(&mut self, rhs: Self) {
107 for (k, v) in rhs.e_m.mp {
108 self.e_m.insert(k, v);
109 }
110 for (k, v) in rhs.m_e.mp {
111 self.m_e.insert(k, v);
112 }
113 }
114}