advent-of-code-client 0.1.1

CLI and crate library to interact with Advent of Code
Documentation
use std::{
    collections::HashMap,
    fs,
    path::{Path, PathBuf},
};

use crate::{Day, Level, Year};

const STARS_DIRECTORY: &str = ".stars";

pub(crate) struct ScoreMap {
    year: Year,
    map: HashMap<String, u8>,
}

impl ScoreMap {
    pub fn load(year: Year) -> ScoreMap {
        let filename = Self::get_filename(year);
        let content = match fs::read_to_string(filename.as_path()) {
            Ok(value) => value,
            Err(err) => match err.kind() {
                std::io::ErrorKind::NotFound => {
                    return ScoreMap {
                        year,
                        map: HashMap::new(),
                    }
                }
                _ => panic!("{}", err),
            },
        };
        match serde_json::from_str(&content) {
            Ok(map) => ScoreMap { year, map },
            Err(_) => panic!("Unable to parse stars"),
        }
    }

    pub fn get_score_for_day(&self, day: Day) -> Option<Level> {
        self.map
            .get(&Self::day_to_key(day))
            .map(|x| Level::from(*x))
    }

    pub fn set_score_for_day(&mut self, day: Day, score: &Level) {
        self.map.insert(Self::day_to_key(day), score.as_int());
        self.store();
    }

    fn day_to_key(day: Day) -> String {
        format!("day{}", day)
    }

    fn get_filename(year: Year) -> PathBuf {
        Path::new(STARS_DIRECTORY).join(format!("{}.json", year.as_int()))
    }

    fn store(&self) {
        fs::create_dir_all(STARS_DIRECTORY).unwrap();
        let filename = Self::get_filename(self.year);
        match serde_json::to_string(&self.map) {
            Ok(content) => fs::write(filename, content).unwrap(),
            Err(err) => panic!("Unable to serialize scores: {}", err),
        };
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn serialize_empty_test() {
        let data: HashMap<&str, u8> = HashMap::new();
        assert_eq!(serde_json::to_string(&data).unwrap(), "{}");
    }
}