1pub mod bells;
3pub mod link;
5pub mod notice;
7
8use crate::school::{bells::BellTime, link::Link, notice::Notice};
9use colored::Colorize;
10use linked_hash_map::LinkedHashMap;
11use serde::{Deserialize, Deserializer, Serialize};
12use std::fmt::Display;
13
14pub type Day = Vec<BellTime>;
16
17#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
18#[serde(rename_all = "camelCase")]
19pub struct School {
21 pub name: String,
23 pub notices: Vec<Notice>,
25 pub links: Vec<Link>,
27 pub user_created: bool,
29 #[serde(deserialize_with = "from_map")]
31 pub bell_times: Vec<(String, [Day; 5])>,
32}
33
34fn from_map<'de, D>(deserializer: D) -> Result<Vec<(String, [Day; 5])>, D::Error>
35where
36 D: Deserializer<'de>,
37{
38 let s: LinkedHashMap<String, Vec<Day>> = Deserialize::deserialize(deserializer)?;
39 Ok(s.into_iter()
40 .map(|(name, week)| (name, week.try_into().unwrap()))
41 .collect())
42}
43
44impl Display for School {
45 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46 write!(f, "{: <40} ", self.name)?;
47 write!(
48 f,
49 "{}",
50 format!(
51 "({} notices, {} links, {} weeks, {} bells)",
52 self.notices.len(),
53 self.links.len(),
54 self.bell_times.len(),
55 self.bell_times
56 .iter()
57 .map(|(_, days)| days.iter().flatten().count())
58 .sum::<usize>()
59 )
60 .dimmed()
61 )?;
62 Ok(())
63 }
64}