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, pub info: Option, } 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 { 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 = 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 { Some(self.cmp(other)) } } impl cmp::PartialEq for Piece { fn eq(&self, _: &Self) -> bool { false } } impl cmp::Eq for Piece {}