use std::collections::HashMap;
use super::Graph;
type ST = HashMap<String, usize>;
pub struct SymbolGraph {
st: ST,
keys: Vec<String>,
_g: Graph,
}
impl SymbolGraph {
pub fn new(stream: &str, sp: &str) -> Self {
let mut st = ST::new();
let lines = stream.lines();
for line in lines {
let a: Vec<&str> = line.trim().split(sp).filter(|it| !it.is_empty()).collect();
for key in a {
if !st.contains_key(key) {
st.insert(key.to_string(), st.len());
}
}
}
let mut keys = vec!["".to_string(); st.len()];
for (key, value) in st.iter() {
keys[*value] = key.clone();
}
let mut g = Graph::new(keys.len());
let lines = stream.lines();
for line in lines {
let a: Vec<&str> = line.trim().split(sp).filter(|it| !it.is_empty()).collect();
if !a.is_empty() {
let v = *st.get(a[0]).unwrap();
for w in a.into_iter().skip(1) {
g.add_edge(v, *st.get(w).unwrap());
}
}
}
SymbolGraph { st, keys, _g: g }
}
pub fn contains(&self, key: &str) -> bool {
self.st.contains_key(key)
}
pub fn index(&self, key: &str) -> usize {
*self.st.get(key).unwrap()
}
pub fn name(&self, v: usize) -> &str {
&self.keys[v]
}
}
#[cfg(test)]
mod test {
use super::SymbolGraph;
#[test]
fn test() {
let sg = SymbolGraph::new(
r#"
a b
c d
e f
a d
"#,
" ",
);
assert_eq!(sg.contains("a"), true);
assert_eq!(sg.contains("f"), true);
assert_eq!(sg.contains("aa"), false);
assert_eq!(sg.index("a"), 0);
assert_eq!(sg.index("b"), 1);
assert_eq!(sg.index("c"), 2);
assert_eq!(sg.index("d"), 3);
assert_eq!(sg.index("e"), 4);
assert_eq!(sg.index("f"), 5);
assert_eq!(sg.name(0), "a");
assert_eq!(sg.name(5), "f");
}
}