graph-store 0.4.0

Access to graph stores over the SPARQL 1.1 Graph Store HTTP Protocol
use std::collections::HashMap;
use std::fmt::Debug;
use std::hash::{Hash, Hasher};

#[derive(Debug, Eq, PartialEq)]
pub struct Variable {
    name: String,
}

impl Hash for Variable {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.name.hash(state);
    }
}

impl From<&str> for Variable {
    fn from(s: &str) -> Self {
        Variable {
            name: s.to_string(),
        }
    }
}

#[derive(Debug)]
pub struct Table<A> {
    pub variables: Vec<Variable>,
    pub bindings: Vec<HashMap<Variable, A>>,
}

impl<A> Table<A> {
    pub fn from<B>(
        variables: Vec<String>,
        bindings: Vec<HashMap<String, B>>,
        transform: fn(B) -> A,
    ) -> Table<A> {
        Table {
            bindings: bindings
                .into_iter()
                .map(|binding| {
                    binding
                        .into_iter()
                        .map(|(k, v)| (Variable::from(k.as_str()), transform(v)))
                        .collect()
                })
                .collect(),
            variables: variables
                .into_iter()
                .map(|v| Variable { name: v })
                .collect(),
        }
    }
}

#[cfg(test)]
mod tests {
    use crate::table::Table;
    use std::collections::HashMap;
    use std::iter::FromIterator;

    #[test]
    fn can_create_tables() {
        let vars = vec!["a".to_string(), "b".to_string()];
        let bindings = vec![
            HashMap::from_iter(vec![("a".to_string(), "c"), ("b".to_string(), "d")].into_iter()),
            HashMap::from_iter(vec![("b".to_string(), "f"), ("a".to_string(), "e")].into_iter()),
        ];
        let table = Table::from(vars, bindings, |a| a);
        println!("Result: {:?}", table);
    }

    #[test]
    fn can_iterate() {
        let vars = vec!["a".to_string(), "b".to_string()];
        let bindings = vec![
            HashMap::from_iter(vec![("a".to_string(), "c"), ("b".to_string(), "d")].into_iter()),
            HashMap::from_iter(vec![("b".to_string(), "f"), ("a".to_string(), "e")].into_iter()),
        ];
        let table = Table::from(vars, bindings, |a| a);
        for v in &table.variables {
            print!("|{:?}", v.name);
        }
        println!("|\n|---|---|");
        for row in &table.bindings {
            for v in &table.variables {
                print!("|{:?}", row.get(&v).unwrap());
            }
            println!("|");
        }
    }
}