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
use serde::{
    Deserialize,
    Serialize,
};
use std::path::Path;
mod local;
pub use local::LocalFilesystem;

use crate::Errors;

/// Filesystem errors
#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum FilesystemErrors {
    FilesystemNotFound,
    FileNotFound,
    FileNotSupported,
    PermissionDenied,
}

/// Filesystem interface
pub trait Filesystem {
    fn read_file_by_path(&self, path: &str) -> Result<FileInfo, Errors>;
    fn list_dir_by_path(&self, path: &str) -> Result<Vec<DirItemInfo>, Errors>;
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct DirItemInfo {
    pub path: String,
    pub name: String,
    pub is_file: bool,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum FileFormat {
    Unknown,
    Binary,
    Text(String),
}

/// Returns the content format of the give file
///
/// # Arguments
///
/// * `path`   - The path of the file
///
pub fn get_format_from_path(path: &str) -> FileFormat {
    if let Some(ext) = Path::new(path).extension() {
        match ext.to_str().unwrap() {
            "rs" => FileFormat::Text("Rust".to_string()),
            _ => FileFormat::Unknown,
        }
    } else {
        FileFormat::Unknown
    }
}

/// Contains information about a file
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct FileInfo {
    pub content: String,
    pub format: FileFormat,
    pub path: String,
}

impl FileInfo {
    pub fn new(path: &str, content: String) -> Self {
        Self {
            content,
            format: get_format_from_path(path),
            path: path.to_owned(),
        }
    }
}