Skip to content
Snippets Groups Projects
file_handlers.rs 1.57 KiB
use std::{fs, path::PathBuf};

use mime::Mime;

use crate::handling::response::{ResponseBody, Status};

#[derive(Debug)]
pub struct NamedFile {
    pub content_len: usize,
    pub content_type: Mime,
    pub content: Vec<u8>,
}

impl ResponseBody for NamedFile {
    fn get_data(&self) -> Vec<u8> {
        self.content.clone()
    }

    fn get_mime(&self) -> Mime {
        self.content_type.clone()
    }

    fn get_len(&self) -> usize {
        self.content_len
    }
}

impl NamedFile {
    pub fn open(path: PathBuf) -> Result<NamedFile, Status> {
        let path = proove_path(path);
        let data = fs::read(&path);
        let data = match data {
            Ok(dat) => dat,
            Err(_) => {
                return Err(Status::NotFound);
            }
        };
        Ok(NamedFile {
            content_len: data.len(),
            content_type: find_mimetype(path.to_str().unwrap()),
            content: data,
        })
    }
}

fn proove_path(path: PathBuf) -> PathBuf {
    PathBuf::from(
        path.to_str()
            .unwrap()
            .split("/")
            .filter(|&val| val != ".." && val != "")
            .collect::<Vec<&str>>()
            .join("/"),
    )
}

pub fn find_mimetype(filename: &str) -> Mime {
    match filename.split('.').last() {
        Some(v) => match v {
            "png" => mime::IMAGE_PNG,
            "jpg" => mime::IMAGE_JPEG,
            "json" => mime::APPLICATION_JSON,
            "html" => mime::TEXT_HTML,
            "css" => mime::TEXT_CSS,
            &_ => mime::TEXT_PLAIN,
        },
        None => mime::TEXT_PLAIN,
    }
}