Copy euph-api-related parts from cove

Also includes the required dependencies and some minor changes to the
module structure, as well as all the clippy and rustc warnings.
This commit is contained in:
Joscha 2022-08-18 00:46:16 +02:00
parent 629ce3ceb9
commit 1495095fa8
11 changed files with 1524 additions and 12 deletions

68
src/replies.rs Normal file
View file

@ -0,0 +1,68 @@
use std::collections::HashMap;
use std::hash::Hash;
use std::result;
use std::time::Duration;
use tokio::sync::oneshot::{self, Receiver, Sender};
use tokio::time;
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("timed out")]
TimedOut,
#[error("canceled")]
Canceled,
}
pub type Result<T> = result::Result<T, Error>;
#[derive(Debug)]
pub struct PendingReply<R> {
timeout: Duration,
result: Receiver<R>,
}
impl<R> PendingReply<R> {
pub async fn get(self) -> Result<R> {
let result = time::timeout(self.timeout, self.result).await;
match result {
Err(_) => Err(Error::TimedOut),
Ok(Err(_)) => Err(Error::Canceled),
Ok(Ok(value)) => Ok(value),
}
}
}
#[derive(Debug)]
pub struct Replies<I, R> {
timeout: Duration,
pending: HashMap<I, Sender<R>>,
}
impl<I: Eq + Hash, R> Replies<I, R> {
pub fn new(timeout: Duration) -> Self {
Self {
timeout,
pending: HashMap::new(),
}
}
pub fn wait_for(&mut self, id: I) -> PendingReply<R> {
let (tx, rx) = oneshot::channel();
self.pending.insert(id, tx);
PendingReply {
timeout: self.timeout,
result: rx,
}
}
pub fn complete(&mut self, id: &I, result: R) {
if let Some(tx) = self.pending.remove(id) {
let _ = tx.send(result);
}
}
pub fn purge(&mut self) {
self.pending.retain(|_, tx| !tx.is_closed());
}
}