summaryrefslogtreecommitdiff
path: root/src/piece.rs
blob: 82d0313d4e673e4b8d679099fd8e23e923461e90 (plain)
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
use std::path::PathBuf;
use std::collections::HashMap;
use std::fs;
use std::io;
use std::cmp;
use crate::picture::{Picture, ConversionError};
use crate::context::Context;
use tera::Context as WebContext;
use serde::Serialize;

#[derive(Debug, thiserror::Error)]
pub enum RenderError {
    #[error("saving to file")]
    Io {
        #[from]
        source: io::Error,
    },
    #[error("rendering template")]
    Templating {
        #[from]
        source: tera::Error,
    },
}

#[derive(Debug, Serialize)]
pub struct Piece {
    pub pic: Picture,

    pub scaled: HashMap<String, PathBuf>,
    pub info: Option<String>,
}

pub fn create_index(ctx: &Context, pieces: &[Piece]) -> Result<(), RenderError> {
    let mut web_ctx = WebContext::new();
    web_ctx.insert("pieces", pieces);
    web_ctx.insert("opts", &ctx.options);

    println!("Rendering index template");

    // Open file for writing and render template
    let mut wr = fs::File::create(ctx.options.builddir.join("index.html"))?;
    let mut wr = io::BufWriter::new(&mut wr);

    ctx.tmpl.render_to("index.html", &web_ctx, &mut wr)?;
    Ok(())
}

impl Piece {
    pub fn new(ctx: &Context, pic: Picture) -> Result<Self, ConversionError> {
        println!("Creating piece from file {}", pic.path.display());
        let mut conv = pic.convert()?;
        let mut scaled = HashMap::with_capacity(ctx.config.sizes.capacity());

        // Create all needed sizes
        for (id, size) in ctx.config.sizes.iter() {
            scaled.insert(id.clone(), conv.get_size(ctx, *size)?);
        }

        let info: Option<String> = pic.path.file_name()
            .map(|name| name.to_str()).flatten()
            .map(|name| ctx.config.info.get(name).map(|s| s.clone())).flatten();

        Ok(Piece {
            pic, scaled, info,
        })
    }
}

impl cmp::Ord for Piece {
    fn cmp(&self, other: &Self) -> cmp::Ordering {
        self.pic.taken_chrono.cmp(&other.pic.taken_chrono)
    }
}

impl cmp::PartialOrd for Piece {
    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
        Some(self.cmp(other))
    }
}

impl cmp::PartialEq for Piece {
    fn eq(&self, _: &Self) -> bool {
        false
    }
}

impl cmp::Eq for Piece {}