1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
use std::collections::HashMap;
use std::fs::File;
use std::io::Seek;
use std::io::Write;
use std::path::Path;

use super::*;

#[derive(Debug)]
pub struct RecipeSet {
    pub recipes: HashMap<Uuid, Recipe>,
}

impl RecipeSet {
    pub fn new() -> RecipeSet {
        RecipeSet {
            recipes: HashMap::new(),
        }
    }

    pub fn from_file<P: AsRef<Path>>(path: P) -> Result<RecipeSet, Error> {
        let file = File::open(path)?;
        let mut archive = zip::ZipArchive::new(file)?;

        let mut recipes = HashMap::new();

        for i in 0..archive.len() {
            let file = archive.by_index(i).unwrap();
            let recipe = Recipe::from_reader(file)?;
            recipes.insert(recipe.uid.clone(), recipe);
        }

        Ok(RecipeSet { recipes: recipes })
    }

    pub fn to_writer<W: Write + Seek>(&self, writer: W) -> Result<(), Error> {
        let mut zip = zip::ZipWriter::new(writer);
        let options =
            zip::write::FileOptions::default().compression_method(zip::CompressionMethod::Stored);

        for (_, recipe) in &self.recipes {
            zip.start_file(&format!("{}.paprikarecipe", recipe.name), options)?;
            recipe.to_writer(&mut zip)?;
        }

        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use crate::RecipeSet;

    #[test]
    fn from_file() {
        let set =
            RecipeSet::from_file("src/test/Neo-Neapolitan Pizza Dough.paprikarecipes").unwrap();
        assert!(set
            .recipes
            .values()
            .find(|r| r.name == "Neo-Neapolitan Pizza Dough")
            .is_some())
    }
}