1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use std::collections::BTreeMap;
use std::fmt;

#[derive(Debug)]
pub struct Record {
    pub english: String,
    pub michuhu: String,
}

#[derive(Debug)]
pub enum Answer {
    One(String),
    Many(Vec<String>),
}

impl Answer {
    pub fn join(&mut self, b: Self) {
        let mut t = Answer::One(String::new());
        std::mem::swap(&mut t, self);
        use Answer::*;
        *self = match (t, b) {
            (One(o), Many(mut m)) | (Many(mut m), One(o)) => {
                if !m.contains(&o) {
                    m.push(o);
                }
                Many(m)
            }
            (Many(mut ma), Many(mb)) => {
                for o in mb {
                    if !ma.contains(&o) {
                        ma.push(o);
                    }
                }
                Many(ma)
            }
            (One(a), One(b)) => {
                if a == b {
                    One(a)
                } else {
                    Many(vec![a, b])
                }
            }
        }
    }
}

impl fmt::Display for Answer {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Answer::One(s) => write!(f, "{}", s),
            Answer::Many(v) => {
                let mut coma = "";
                for x in v {
                    write!(f, "{}{}", x, coma)?;
                    coma = " , "
                }
                Ok(())
            }
        }
    }
}

#[derive(Debug)]
pub struct AnsMap {
    pub mp: BTreeMap<String, Answer>,
}

impl AnsMap {
    pub fn new() -> Self {
        AnsMap {
            mp: BTreeMap::new(),
        }
    }

    pub fn insert_s(&mut self, k: String, v: String) {
        self.insert(k, Answer::One(v))
    }

    pub fn insert(&mut self, k: String, v: Answer) {
        if let Some(gm) = self.mp.get_mut(&k) {
            gm.join(v)
        } else {
            self.mp.insert(k, v);
        }
    }
}

#[derive(Debug)]
pub struct TwoWayMap {
    pub e_m: AnsMap,
    pub m_e: AnsMap,
}

impl TwoWayMap {
    pub fn new() -> Self {
        TwoWayMap {
            e_m: AnsMap::new(),
            m_e: AnsMap::new(),
        }
    }
    pub fn insert(&mut self, r: Record) {
        self.e_m.insert_s(r.english.clone(), r.michuhu.clone());
        self.m_e.insert_s(r.michuhu, r.english);
    }

    pub fn merge(&mut self, rhs: Self) {
        for (k, v) in rhs.e_m.mp {
            self.e_m.insert(k, v);
        }
        for (k, v) in rhs.m_e.mp {
            self.m_e.insert(k, v);
        }
    }
}