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
|
pub mod connectors;
pub mod manager;
use std::{thread::sleep, time::Duration};
use crate::executor::{Executor, tasks::IntoTask};
#[derive(Debug)]
pub enum Result<T: std::fmt::Display + IntoTask, E: std::fmt::Debug> {
Ok(T),
Err(E),
}
pub trait Connection {
type Ok: std::fmt::Display + IntoTask + AsRef<str> = String;
type Err: std::fmt::Debug;
// should use channel to notify update
fn update(&self) -> Result<Self::Ok, Self::Err>; // None if no update(content is same)
// TODO: queue failed ntfy
fn ntfy(&self, data: String) -> Result<Self::Ok, Self::Err>;
fn is_prev(&mut self, str: &Self::Ok) -> bool;
fn force_network(&mut self);
fn reinit(&mut self) {
sleep(Duration::from_millis(500));
_ = Executor::new("network", ["on".to_string()]);
self.force_network();
}
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
self.reinit();
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,
};
// FIXME: handle the errors... peak prod code
self.ntfy(
Executor::new(task, it.map(str::to_string))
.unwrap()
.run()
.unwrap()
.clone()
.unwrap(),
); //.unwrap()
}
Result::Err(e) => {
#[cfg(debug_assertions)]
std::eprintln!(
"[{}:{}:{}] {} = {:#?}",
std::file!(),
std::line!(),
std::column!(),
std::stringify!(e),
&&e as &dyn std::fmt::Debug,
);
}
}
}
}
}
|