use crate::backend::{private, BackendError, OutputBuffers};
pub trait PendingDispatch: private::Sealed + Send + Sync {
fn is_ready(&self) -> bool;
fn await_result(self: Box<Self>) -> Result<Vec<Vec<u8>>, BackendError>;
fn await_result_into(self: Box<Self>, outputs: &mut OutputBuffers) -> Result<(), BackendError> {
let result = self.await_result()?;
crate::backend::dispatch_result::replace_output_buffers_preserving_slots(result, outputs);
Ok(())
}
fn await_result_async(
self: Box<Self>,
) -> impl std::future::Future<Output = Result<Vec<Vec<u8>>, BackendError>> + Send
where
Self: Sized,
{
async { self.await_result() }
}
}
pub(crate) struct ReadyPending {
pub(crate) outputs: Vec<Vec<u8>>,
}
impl private::Sealed for ReadyPending {}
impl PendingDispatch for ReadyPending {
fn is_ready(&self) -> bool {
true
}
fn await_result(self: Box<Self>) -> Result<Vec<Vec<u8>>, BackendError> {
Ok(self.outputs)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn pending_dispatch_default_into_preserves_output_slots() {
let mut outputs = vec![Vec::with_capacity(8)];
let outputs_addr = outputs.as_ptr() as usize;
let slot_addr = outputs[0].as_ptr() as usize;
Box::new(ReadyPending {
outputs: vec![vec![1, 2, 3]],
})
.await_result_into(&mut outputs)
.expect("Fix: ready pending output should write into caller storage");
assert_eq!(outputs, vec![vec![1, 2, 3]]);
assert_eq!(outputs.as_ptr() as usize, outputs_addr);
assert_eq!(outputs[0].as_ptr() as usize, slot_addr);
}
}