diff options
Diffstat (limited to 'src/data.rs')
-rw-r--r-- | src/data.rs | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/src/data.rs b/src/data.rs new file mode 100644 index 0000000..2734f38 --- /dev/null +++ b/src/data.rs @@ -0,0 +1,66 @@ +use crate::schema::{Person, Team}; +use failure::{Error, ResultExt}; +use serde::Deserialize; +use std::collections::HashMap; +use std::ffi::OsStr; + +#[derive(Debug)] +pub(crate) struct Data { + people: HashMap<String, Person>, + teams: HashMap<String, Team>, +} + +impl Data { + pub(crate) fn load() -> Result<Self, Error> { + let mut data = Data { + people: HashMap::new(), + teams: HashMap::new(), + }; + + data.load_dir("people", |this, person: Person| { + this.people.insert(person.github().to_string(), person); + })?; + + data.load_dir("teams", |this, team: Team| { + this.teams.insert(team.name().to_string(), team); + })?; + + Ok(data) + } + + fn load_dir<T, F>(&mut self, dir: &str, f: F) -> Result<(), Error> + where + T: for<'de> Deserialize<'de>, + F: Fn(&mut Self, T), + { + for entry in std::fs::read_dir(dir)? { + let path = entry?.path(); + + if path.is_file() && path.extension() == Some(OsStr::new("toml")) { + let content = std::fs::read(&path) + .with_context(|_| format!("failed to read {}", path.display()))?; + let parsed: T = toml::from_slice(&content) + .with_context(|_| format!("failed to parse {}", path.display()))?; + f(self, parsed); + } + } + + Ok(()) + } + + pub(crate) fn team(&self, name: &str) -> Option<&Team> { + self.teams.get(name) + } + + pub(crate) fn teams(&self) -> impl Iterator<Item = &Team> { + self.teams.values() + } + + pub(crate) fn person(&self, name: &str) -> Option<&Person> { + self.people.get(name) + } + + pub(crate) fn people(&self) -> impl Iterator<Item = &Person> { + self.people.values() + } +} |