aboutsummaryrefslogtreecommitdiff
path: root/crates/vfs/src/loader.rs
blob: 6de2e5b3f9501f5560e9e11fcdf8b00f9a776d2e (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
//! Object safe interface for file watching and reading.
use std::fmt;

use paths::{AbsPath, AbsPathBuf};

#[derive(Debug)]
pub enum Entry {
    Files(Vec<AbsPathBuf>),
    Directory { path: AbsPathBuf, include: Vec<String> },
}

#[derive(Debug)]
pub struct Config {
    pub load: Vec<Entry>,
    pub watch: Vec<usize>,
}

pub enum Message {
    Progress { n_total: usize, n_done: usize },
    Loaded { files: Vec<(AbsPathBuf, Option<Vec<u8>>)> },
}

pub type Sender = Box<dyn Fn(Message) + Send>;

pub trait Handle: fmt::Debug {
    fn spawn(sender: Sender) -> Self
    where
        Self: Sized;
    fn set_config(&mut self, config: Config);
    fn invalidate(&mut self, path: AbsPathBuf);
    fn load_sync(&mut self, path: &AbsPath) -> Option<Vec<u8>>;
}

impl Entry {
    pub fn rs_files_recursively(base: AbsPathBuf) -> Entry {
        Entry::Directory { path: base, include: globs(&["*.rs", "!/.git/"]) }
    }
    pub fn local_cargo_package(base: AbsPathBuf) -> Entry {
        Entry::Directory { path: base, include: globs(&["*.rs", "!/target/", "!/.git/"]) }
    }
    pub fn cargo_package_dependency(base: AbsPathBuf) -> Entry {
        Entry::Directory {
            path: base,
            include: globs(&["*.rs", "!/tests/", "!/examples/", "!/benches/", "!/.git/"]),
        }
    }
}

fn globs(globs: &[&str]) -> Vec<String> {
    globs.iter().map(|it| it.to_string()).collect()
}

impl fmt::Debug for Message {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Message::Loaded { files } => {
                f.debug_struct("Loaded").field("n_files", &files.len()).finish()
            }
            Message::Progress { n_total, n_done } => f
                .debug_struct("Progress")
                .field("n_total", n_total)
                .field("n_done", n_done)
                .finish(),
        }
    }
}

#[test]
fn handle_is_object_safe() {
    fn _assert(_: &dyn Handle) {}
}