aboutsummaryrefslogtreecommitdiff
path: root/src/file_handler/mod.rs
blob: 4932ef17f567f70066e8ce480fd03b6ec1afc81a (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
mod file_strategies;

use file_strategies::file::Strategy as FileStrategy;
use file_strategies::gemini::Strategy as GeminiStrategy;
use file_strategies::layout::Strategy as LayoutStrategy;

use std::path::PathBuf;
use std::fs::read_to_string;

pub struct FileHandler {
   pub strategies: Vec<Box<dyn FileHandlerStrategy>>,
   pub layout: Option<String>
}

impl Default for FileHandler {
    fn default() -> FileHandler {
        FileHandler {
            strategies: vec![
                Box::new(GeminiStrategy{}),
                Box::new(LayoutStrategy{}),
                Box::new(FileStrategy{}),
            ],
            layout: None
        }
    }
}

impl FileHandler {
    pub fn identify(&self, path: &PathBuf) -> FileType {
        for strategy in self.strategies.iter() {
            if strategy.is(&path) {
                return strategy.identify();
            }
        }
        FileType::Unknown
    }

    pub fn get_layout_or_panic(&mut self, files: &Vec<File>) -> Result<(), &str> {
        for file in files {
            match file.file_type {
                FileType::Layout => {
                    let layout_text = read_to_string(&file.path).unwrap();
                    self.layout = Some(layout_text);
                    return Ok(());
                },
                _ => {}
            }
        }
        Err("No layout found. Please ensure there's a _layout.html file at the root")
    }

    pub fn handle_all(&self, source: &PathBuf, destination: &PathBuf, files: &Vec<File>) {
        for file in files {
            self.handle(source, destination, file);
        }
    }

    pub fn handle(&self, source: &PathBuf, destination: &PathBuf, file: &File) {
        for strategy in self.strategies.iter() {
            if strategy.can_handle(&file.file_type) {
                let layout = self.layout.as_ref().unwrap();
                return strategy.handle(source, destination, file, layout);
            }
        }
    }
}

pub trait FileHandlerStrategy {
    fn is(&self, path: &PathBuf) -> bool;
    fn identify(&self) -> FileType;
    fn can_handle(&self, file_type: &FileType) -> bool;
    fn handle(&self, source: &PathBuf, destination: &PathBuf, file: &File, layout: &String);
}

pub enum FileType {
    Gemini,
    File,
    Layout,
    Unknown,
}

pub struct File {
    pub path: PathBuf,
    pub file_type: FileType,
}