2022-05-07 22:45:24 -04:00

102 lines
3.1 KiB
Rust

use tokio::sync::mpsc;
use super::github_endpoint_watcher::GithubEndpointWatcher;
pub struct GithubCtl<'a> {
username: &'a str,
token: &'a str,
event_writer: mpsc::Sender<serde_json::Value>,
event_reader: mpsc::Receiver<serde_json::Value>,
}
impl<'a> GithubCtl<'a> {
pub fn new(username: &'a str, token: &'a str) -> Result<Self, Box<dyn std::error::Error>> {
let (tx, rx) = mpsc::channel::<serde_json::Value>(100);
Ok(GithubCtl {
username,
token,
event_writer: tx,
event_reader: rx,
})
}
pub async fn get_event(&mut self) -> Result<serde_json::Value, Box<dyn std::error::Error>> {
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<O, R>(
&mut self,
owner: O,
repo: R,
) -> Result<(), Box<dyn std::error::Error>>
where
O: AsRef<str>,
R: AsRef<str>,
{
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<O>(&mut self, org: O) -> Result<(), Box<dyn std::error::Error>>
where
O: AsRef<str>,
{
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<dyn std::error::Error>> {
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<U>(&mut self, url: U)
where
U: Into<String>,
{
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.");
}
}
});
}
}