summaryrefslogtreecommitdiff
path: root/src/client/connector.rs
blob: 88b193936e13d23342228ec6ce642687e2d06c09 (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
pub(crate) mod connectors;
pub(crate) mod manager;

use std::{thread::sleep, time::Duration};

use crate::executor::{Executor, tasks::IntoTask};

pub(crate) enum Result<T: std::fmt::Display + IntoTask, E: std::fmt::Display> {
    Ok(T),
    Err(E),
}

pub(crate) trait Connection {
    type Ok: std::fmt::Display + IntoTask + AsRef<str> = String;
    type Err: std::fmt::Display;

    // should use channel to notify update
    fn update(&self) -> Result<Self::Ok, Self::Err>; // None if no update(content is same)

    fn ntfy(&self, data: String);

    fn is_prev(&mut self, str: &Self::Ok) -> bool;

    fn r#loop(&mut self) -> ! {
        loop {
            // tradeoff: if I put this at the ened of the loop, then the continue would just skip it, and continue doing update() until with no waiting, this wastes lot of cpu/IO
            // however, of course we can add a manual sleep before it continue and put this in the end, but that's code duplication
            // the cons of the current approch is that the first time we've entered, it would start sleeping
            sleep(Duration::from_millis(500));
            match self.update() {
                Result::Ok(s) => {
                    if self.is_prev(&s) {
                        continue;
                    }

                    let mut it = s.as_ref().split_whitespace();
                    let task = match it.next() {
                        Some(t) => t,
                        None => continue,
                    };
                    let args: String = it.collect();
                    // FIXME: handle the errors... peak prod code
                    self.ntfy(
                        Executor::new(task, args)
                            .unwrap()
                            .run()
                            .unwrap()
                            .clone()
                            .unwrap(),
                    );
                }
                Result::Err(e) => eprintln!("Error: {}", e),
            }
        }
    }
}