pillow_fs/
lib.rs

1use mime_guess::MimeGuess;
2use std::{fs, io::Read, path::Path};
3
4pub struct FS {}
5
6#[derive(Debug, Clone)]
7pub struct File {
8    pub path: String,
9    pub metadata: fs::Metadata,
10    pub file_type: fs::FileType,
11    pub content: Option<Vec<u8>>,
12    pub content_type: Option<String>,
13    pub buffer: Option<Vec<u8>>,
14}
15
16impl File {
17    pub fn from_dir_entry(path: String, dir_entry: &fs::DirEntry) -> File {
18        let mut content: Option<Vec<u8>> = None;
19        let metadata = dir_entry.metadata().unwrap();
20        let mut content_type: Option<String> = None;
21        let buffer: Option<Vec<u8>> = None;
22
23        if metadata.clone().is_file() {
24            let is_other_type_extension = if let Some(extension) = path.rsplit('.').next() {
25                !(extension.to_lowercase() == "html") || !(extension.to_lowercase() == "hbs")
26            } else {
27                false
28            };
29
30            if is_other_type_extension {
31                content = Some(FS::read_to_buf(&path))
32            } else {
33                content = Some(FS::read_to_string(&path));
34            }
35
36            content_type = Some(FS::get_mime_type(path.as_str()));
37        }
38
39        File {
40            path,
41            metadata,
42            file_type: dir_entry.file_type().unwrap().clone(),
43            content,
44            content_type,
45            buffer,
46        }
47    }
48}
49
50impl FS {
51    /// Return a Vec for All files in directory
52    ///
53    /// # Arguments
54    ///
55    /// * `path` - Path where the file is located
56    ///
57    /// # Examples
58    ///
59    /// ```rust
60    /// use FS;
61    ///
62    /// fn (){
63    ///     let resources = FS::get_all_in_directories("resources");
64    /// }
65    /// ```
66    pub fn get_all_in_directories(path: &str) -> Vec<File> {
67        let directory_root = fs::read_dir(path).unwrap();
68        let mut directories_dir_entry = Vec::new();
69        let mut directories: Vec<File> = Vec::new();
70
71        for directory in directory_root {
72            directories_dir_entry.push(directory.unwrap())
73        }
74
75        for directory in &directories_dir_entry {
76            let path = String::from(directory.path().clone().to_str().unwrap());
77
78            directories.push(File::from_dir_entry(path, directory));
79        }
80
81        directories
82    }
83
84    /// Read a file and convert to String
85    ///
86    /// # Arguments
87    ///
88    /// * `path` - Path to read file
89    ///
90    /// # Examples
91    ///
92    /// ```rust
93    /// use FS;
94    ///
95    /// let file = FS::read_to_string("main.js");
96    /// ```
97    pub fn read_to_hex(path: &str) -> String {
98        let mut file = fs::File::open(path).expect("No se pudo abrir el archivo");
99        let mut buffer = Vec::new();
100        file.read_to_end(&mut buffer)
101            .expect("Error al leer el archivo");
102
103        let hex_string: String = buffer.iter().map(|byte| format!("{:02X}", byte)).collect();
104
105        hex_string
106    }
107
108    pub fn read_to_buf(path: &str) -> Vec<u8> {
109        let mut file = fs::File::open(path).expect("No se pudo abrir el archivo");
110        let mut buffer = Vec::new();
111        file.read_to_end(&mut buffer)
112            .expect("Error al leer el archivo");
113
114        buffer
115    }
116
117    pub fn read_to_string(path: &str) -> Vec<u8> {
118        match fs::read_to_string(path) {
119            Ok(content) => content.as_bytes().into(),
120            Err(_) => FS::read_to_buf(path),
121        }
122    }
123
124    fn get_mime_type(path: &str) -> String {
125        let path = Path::new(path);
126
127        MimeGuess::from_path(path)
128            .first_or_octet_stream()
129            .to_string()
130    }
131}