diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/client/connector.rs | 41 | ||||
| -rw-r--r-- | src/client/connector/connectors/httpconnector.rs | 25 | ||||
| -rw-r--r-- | src/client/executor.rs | 10 | ||||
| -rw-r--r-- | src/client/executor/tasks.rs | 15 | ||||
| -rw-r--r-- | src/client/main.rs | 6 |
5 files changed, 59 insertions, 38 deletions
diff --git a/src/client/connector.rs b/src/client/connector.rs index 709b91d..cae944b 100644 --- a/src/client/connector.rs +++ b/src/client/connector.rs @@ -1,30 +1,49 @@ pub(crate) mod connectors; pub(crate) mod manager; -use std::{thread::sleep, time}; +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; - type Success: std::fmt::Display = String; // should use channel to notify update - fn update(&self) -> Option<Result<Self::Success, Self::Err>>; // None if no update(content is same) + fn update(&self) -> Option<Result<Self::Ok, Self::Err>>; // None if no update(content is same) + + fn ntfy(&self, data: String); fn r#loop(&self) -> ! { loop { - // if let Some(Err(e)) = self.update() { - // eprintln!("Error: {}", e) - // } match self.update() { - Some(Ok(s)) => { - // _ = self.channel.sender.send(res.clone()); // don't care if receiver is dropped - // _ = executor::new(res.as_str()); + Some(Result::Ok(s)) => { + 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(), + ); } - Some(Err(e)) => eprintln!("Error: {}", e), + Some(Result::Err(e)) => eprintln!("Error: {}", e), _ => {} } - sleep(time::Duration::from_secs(1)); + sleep(Duration::from_millis(500)); } } } diff --git a/src/client/connector/connectors/httpconnector.rs b/src/client/connector/connectors/httpconnector.rs index 2a7c0d8..923df94 100644 --- a/src/client/connector/connectors/httpconnector.rs +++ b/src/client/connector/connectors/httpconnector.rs @@ -1,4 +1,4 @@ -use reqwest::{Error, StatusCode, Url, blocking::get}; +use reqwest::{Error, StatusCode, Url, blocking::Client}; use crate::connector::*; use std::{thread::sleep, time::Duration}; @@ -6,13 +6,16 @@ use std::{thread::sleep, time::Duration}; pub(crate) struct HTTPConnector { prev: String, url: Url, + client: Client, } impl HTTPConnector { - pub fn new(url: &str) -> Result<Self, url::ParseError> { + pub fn new(url: &str) -> std::result::Result<Self, url::ParseError> { Ok(Self { prev: String::new(), url: Url::parse(url)?, + // TODO: keep alive + client: Client::new(), }) } } @@ -34,8 +37,8 @@ impl std::fmt::Display for Err { impl Connection for HTTPConnector { type Err = Err; - fn update(&self) -> Option<Result<Self::Success, Self::Err>> { - let res = match get(self.url.as_str()) { + fn update(&self) -> Option<Result<Self::Ok, Self::Err>> { + let resp = match self.client.get(self.url.as_str()).send() { Ok(resp) => match resp.status() { StatusCode::TOO_MANY_REQUESTS => { sleep(Duration::from_secs(5)); @@ -43,23 +46,25 @@ impl Connection for HTTPConnector { } status => { if !status.is_success() { - return Some(Err(Err::StatusCode(status))); + return Some(Result::Err(Err::StatusCode(status))); } match resp.text() { Ok(text) => text, - Err(e) => return Some(Err(Err::Reqwest(e))), + Err(e) => return Some(Result::Err(Err::Reqwest(e))), } } }, - Err(e) => return Some(Err(Err::Reqwest(e))), + Err(e) => return Some(Result::Err(Err::Reqwest(e))), }; - if res == self.prev { + if resp == self.prev { return None; } - Some(Ok(res)) + Some(Result::Ok(resp)) } - // fn ntfy<T>(&self, data: T) {} + fn ntfy(&self, data: String) { + println!("{}", data) + } } diff --git a/src/client/executor.rs b/src/client/executor.rs index df22c57..5fbba0b 100644 --- a/src/client/executor.rs +++ b/src/client/executor.rs @@ -1,15 +1,15 @@ use crate::executor::tasks::{IntoTask, IntoTaskErr, Task}; -mod tasks; +pub(crate) mod tasks; -struct Executor<'a> { +pub(crate) struct Executor<'a> { task: &'a Task, - args: Box<[&'a str]>, + args: Box<[String]>, output: Option<Result<String, String>>, } impl<'a> Executor<'a> { - fn new(task: impl IntoTask, args: &'a str) -> Result<Self, IntoTaskErr> { + pub(crate) fn new(task: impl IntoTask, args: String) -> Result<Self, IntoTaskErr> { let task = task.into_task()?; Ok(Self { task: task, @@ -18,7 +18,7 @@ impl<'a> Executor<'a> { }) } - fn run(&mut self) -> Option<&Result<String, String>> { + pub(crate) fn run(&mut self) -> Option<&Result<String, String>> { self.output = Some((self.task.exec)(&self.args)); self.output.as_ref() } diff --git a/src/client/executor/tasks.rs b/src/client/executor/tasks.rs index c69b310..4c8cdee 100644 --- a/src/client/executor/tasks.rs +++ b/src/client/executor/tasks.rs @@ -1,6 +1,6 @@ pub(crate) struct Task { pub name: &'static str, - pub exec: fn(&[&str]) -> Result<String, String>, + pub exec: fn(&[String]) -> Result<String, String>, } pub(crate) const TASKS: &[Task] = &[ @@ -14,14 +14,14 @@ pub(crate) const TASKS: &[Task] = &[ }, ]; -fn no_op(_: &[&str]) -> Result<String, String> { +fn no_op(_: &[String]) -> Result<String, String> { Ok("".to_string()) } -fn exec(cmds: &[&str]) -> Result<String, String> { +fn exec(cmds: &[String]) -> Result<String, String> { use std::process::Command; // TODO: fmt and add exit code, and add support for both stdout and stderr, and support for no output - match Command::new(cmds[0]).args(&cmds[1..]).output() { + match Command::new(cmds[0].as_str()).args(&cmds[1..]).output() { Ok(o) => { if o.status.success() { Ok(String::from_utf8(o.stdout) @@ -37,8 +37,9 @@ fn exec(cmds: &[&str]) -> Result<String, String> { } } +#[derive(Debug)] pub(crate) enum IntoTaskErr { - NotFound, + NotFound(String), } pub(crate) trait IntoTask { @@ -52,7 +53,7 @@ impl IntoTask for String { return Ok(task); } } - Err(IntoTaskErr::NotFound) + Err(IntoTaskErr::NotFound(self)) } } @@ -63,6 +64,6 @@ impl IntoTask for &str { return Ok(task); } } - Err(IntoTaskErr::NotFound) + Err(IntoTaskErr::NotFound(self.to_string())) } } diff --git a/src/client/main.rs b/src/client/main.rs index cada2f8..bceaa82 100644 --- a/src/client/main.rs +++ b/src/client/main.rs @@ -1,13 +1,9 @@ #![feature(associated_type_defaults, never_type)] -use std::thread; - use crate::connector::{connectors::httpconnector::HTTPConnector, manager::ConnectorManager}; mod connector; mod executor; fn main() { - ConnectorManager::new(HTTPConnector::new("https://example.com").unwrap()).enter_loop(); - - thread::park(); + ConnectorManager::new(HTTPConnector::new("http://127.0.0.1").unwrap()).enter_loop(); } |
