Skip to content
Snippets Groups Projects
misc.rs 1.52 KiB
Newer Older
Stephen D's avatar
Stephen D committed
use std::{fs::File, io::Read, path::Path};
Stephen D's avatar
Stephen D committed
use anyhow::{bail, Context};
use crate::{
    load::Loadable,
    resp::{Expiry, Response},
    util::slugify,
};
Stephen D's avatar
Stephen D committed
#[derive(Clone)]
pub struct Misc {
    pub url: String,
    content_type: &'static str,
    data: Vec<u8>,
}

impl Loadable for Misc {
Stephen D's avatar
Stephen D committed
    fn load(_: &Path, path: &Path, slug_prefix: &str) -> anyhow::Result<Self> {
        let file_name = path
            .file_name()
            .context("Could not get file name")?
            .to_str()
            .context("Could not convert filename into string")?
            .to_owned();

Stephen D's avatar
Stephen D committed
        let extension = path
            .extension()
            .with_context(|| format!("Could not get extension for {file_name}"))?
            .to_str()
            .context("Extension could not be converted to a string")?;

        let url = slugify(&format!("/{slug_prefix}/{file_name}"));

        let mut data = vec![];
        File::open(path)?.read_to_end(&mut data)?;

        Ok(Self {
            data,
Stephen D's avatar
Stephen D committed
            content_type: content_type(extension)?,
            url,
        })
    }
}

impl Misc {
    pub fn response(self) -> Response {
        Response {
            content_type: self.content_type,
            expiry: Expiry::Year,
Stephen D's avatar
Stephen D committed

fn content_type(ext: &str) -> anyhow::Result<&'static str> {
    let c = match ext {
        "webm" => "video/webm",
        "mp4" => "video/mp4",
Stephen D's avatar
Stephen D committed
        "ico" => "image/x-icon",
Stephen D's avatar
Stephen D committed
        _ => bail!("Unsure how to handle extension {ext}"),
    };

    Ok(c)
}