use std::cell::RefCell;
use serde_json::Value;
use super::{ProtocolError, RequestRegistry, Response};
use crate::engine::DarklyEngine;
pub struct QueuedRequest {
pub id: u64,
pub kind: String,
pub payload: Value,
pub bytes: Vec<u8>,
}
pub struct RequestOutcome {
pub id: u64,
pub result: Result<Response, ProtocolError>,
}
pub enum DrainOutcome {
Busy,
Drained(Vec<RequestOutcome>),
}
pub struct Transport {
registry: RequestRegistry,
queue: RefCell<Vec<QueuedRequest>>,
}
impl Default for Transport {
fn default() -> Self {
Self::new()
}
}
impl Transport {
pub fn new() -> Self {
Transport {
registry: RequestRegistry::new(),
queue: RefCell::new(Vec::new()),
}
}
pub fn registry(&self) -> &RequestRegistry {
&self.registry
}
pub fn enqueue(&self, id: u64, kind: impl Into<String>, payload: Value, bytes: Vec<u8>) {
self.queue.borrow_mut().push(QueuedRequest {
id,
kind: kind.into(),
payload,
bytes,
});
}
pub fn pending(&self) -> usize {
self.queue.borrow().len()
}
pub fn drain_with(&self, engine: &mut DarklyEngine) -> Vec<RequestOutcome> {
let reqs: Vec<QueuedRequest> = self.queue.borrow_mut().drain(..).collect();
reqs.into_iter()
.map(|req| RequestOutcome {
id: req.id,
result: self
.registry
.dispatch(engine, &req.kind, req.payload, &req.bytes),
})
.collect()
}
pub fn try_drain(&self, engine: &RefCell<DarklyEngine>) -> DrainOutcome {
match engine.try_borrow_mut() {
Ok(mut e) => DrainOutcome::Drained(self.drain_with(&mut e)),
Err(_) => DrainOutcome::Busy,
}
}
}