use tokio::sync::mpsc; use super::github_endpoint_watcher::GithubEndpointWatcher; pub struct GithubCtl<'a> { username: &'a str, token: &'a str, event_writer: mpsc::Sender, event_reader: mpsc::Receiver, } impl<'a> GithubCtl<'a> { pub fn new(username: &'a str, token: &'a str) -> Result> { let (tx, rx) = mpsc::channel::(100); Ok(GithubCtl { username, token, event_writer: tx, event_reader: rx, }) } pub async fn get_event(&mut self) -> Result> { if let Some(val) = self.event_reader.recv().await { return Ok(val); } else { return Err("No more events, perhaps all writers hung up?".into()); } } pub async fn watch_repo( &mut self, owner: O, repo: R, ) -> Result<(), Box> where O: AsRef, R: AsRef, { let url = format!( "https://api.github.com/repos/{owner}/{repo}/events", owner = owner.as_ref().trim(), repo = repo.as_ref().trim() ); return Ok(self.watch_list(url).await); } pub async fn watch_org(&mut self, org: O) -> Result<(), Box> where O: AsRef, { let url = format!( "https://api.github.com/users/{username}/events/orgs/{org}", org = org.as_ref().trim(), username = self.username.trim() ); return Ok(self.watch_list(url).await); } pub async fn watch_self(&mut self) -> Result<(), Box> { let url = format!( "https://api.github.com/users/{username}/received_events", username = self.username.trim() ); return Ok(self.watch_list(url).await); } async fn watch_list(&mut self, url: U) where U: Into, { let url = url.into(); let username = self.username.to_string(); let token = self.token.to_string(); let event_stream = self.event_writer.clone(); tokio::spawn(async move { let mut endpoint_watcher = GithubEndpointWatcher::new(username, token, url) .expect("Failed to create endpoint watcher."); loop { let api_result = match endpoint_watcher.get_results().await { Ok(result) => result, Err(_) => { println!("Failed to get results."); return; } }; if let serde_json::Value::Array(events) = api_result { for event in events { if let Err(_) = event_stream.send(event).await { println!("Receiver dropped."); return; } } } else { println!("Unsupported JSON type."); } } }); } }