use super::types::{Request, Response};
use commonware_cryptography::ed25519::PublicKey;
use commonware_utils::channel::{fallible::OneshotExt, mpsc, oneshot};
use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct Processed {
pub origin: PublicKey,
pub request: Request,
pub responded: bool,
}
#[derive(Clone)]
pub struct Handler {
sender: mpsc::UnboundedSender<Processed>,
responses: HashMap<u64, Response>,
respond_by_default: bool,
}
impl Handler {
pub fn new(respond_by_default: bool) -> (Self, mpsc::UnboundedReceiver<Processed>) {
let (sender, receiver) = mpsc::unbounded_channel();
(
Self {
sender,
responses: HashMap::new(),
respond_by_default,
},
receiver,
)
}
pub fn dummy() -> Self {
let (sender, _) = mpsc::unbounded_channel();
Self {
sender,
responses: HashMap::new(),
respond_by_default: true,
}
}
pub fn set_response(&mut self, request_id: u64, response: Response) {
self.responses.insert(request_id, response);
}
}
impl crate::Handler for Handler {
type PublicKey = PublicKey;
type Request = Request;
type Response = Response;
async fn process(
&mut self,
origin: Self::PublicKey,
request: Self::Request,
responder: oneshot::Sender<Self::Response>,
) {
let request_id = request.id;
let should_respond = self.responses.contains_key(&request_id) || self.respond_by_default;
let _ = self.sender.send(Processed {
origin,
request: request.clone(),
responded: should_respond,
});
if let Some(response) = self.responses.get(&request_id) {
responder.send_lossy(response.clone());
} else if self.respond_by_default {
responder.send_lossy(Response {
id: request_id,
result: request.data.wrapping_mul(2) as u64,
});
}
}
}