diff options
Diffstat (limited to 'src/static_api.rs')
-rw-r--r-- | src/static_api.rs | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/src/static_api.rs b/src/static_api.rs new file mode 100644 index 0000000..1beea23 --- /dev/null +++ b/src/static_api.rs @@ -0,0 +1,93 @@ +use crate::data::Data; +use rust_team_data::v1; +use failure::Error; +use log::info; +use std::path::Path; +use indexmap::IndexMap; + +pub(crate) struct Generator<'a> { + dest: &'a Path, + data: &'a Data, +} + +impl<'a> Generator<'a> { + pub(crate) fn new(dest: &'a Path, data: &'a Data) -> Result<Generator<'a>, Error> { + if dest.is_dir() { + std::fs::remove_dir_all(&dest)?; + } + std::fs::create_dir_all(&dest)?; + + Ok(Generator { dest, data }) + } + + pub(crate) fn generate(&self) -> Result<(), Error> { + self.generate_teams()?; + Ok(()) + } + + fn generate_teams(&self) -> Result<(), Error> { + let mut teams = IndexMap::new(); + + for team in self.data.teams() { + let leads = team.leads(); + let mut members = Vec::new(); + for github_name in &team.members(&self.data)? { + if let Some(person) = self.data.person(github_name) { + members.push(v1::TeamMember { + name: person.name().into(), + github: (*github_name).into(), + is_lead: leads.contains(github_name), + }); + } + } + members.sort_by_key(|member| member.github.to_lowercase()); + members.sort_by_key(|member| !member.is_lead); + + let team_data = v1::Team { + name: team.name().into(), + kind: if team.is_wg() { + v1::TeamKind::WorkingGroup + } else { + v1::TeamKind::Team + }, + subteam_of: team.subteam_of().map(|st| st.into()), + members, + website_data: team.website_data().map(|ws| v1::TeamWebsite { + name: ws.name().into(), + description: ws.description().into(), + page: ws.page().unwrap_or(team.name()).into(), + email: ws.email().map(|e| e.into()), + repo: ws.repo().map(|e| e.into()), + discord: ws.discord().map(|i| v1::DiscordInvite { + channel: i.channel.into(), + url: i.url.into(), + }), + weight: ws.weight(), + }), + }; + + self.add(&format!("v1/teams/{}.json", team.name()), &team_data)?; + teams.insert(team.name().into(), team_data); + } + + teams.sort_keys(); + self.add( + "v1/teams.json", + &v1::Teams { teams }, + )?; + Ok(()) + } + + fn add<T: serde::Serialize>(&self, path: &str, obj: &T) -> Result<(), Error> { + info!("writing API object {}...", path); + let dest = self.dest.join(path); + if let Some(parent) = dest.parent() { + if !parent.exists() { + std::fs::create_dir_all(parent)?; + } + } + let json = serde_json::to_string_pretty(obj)?; + std::fs::write(&dest, json.as_bytes())?; + Ok(()) + } +} |