use std::fmt::Debug;
use std::mem::MaybeUninit;
use std::task::{Context, Poll};
use std::pin::Pin;
use std::borrow::Borrow;
use std::fmt;
use std::sync::{Arc, Mutex};
use std::ops::{Deref, DerefMut};
#[derive(Clone)]
pub struct Request<T: Clone + Debug>{
data: Arc<Mutex<MaybeUninit<T>>>,
data_ready: Arc<Mutex<bool>>,
}
impl<Req: Clone + Debug> std::future::Future for Request<Req> {
type Output = Req;
fn poll(self: Pin<&mut Self>, _ctx: &mut Context) -> Poll<Self::Output>{
let ready_state = self.data_ready.lock().unwrap();
if *ready_state.deref() {
let data = self.data.lock().unwrap();
return Poll::Ready( unsafe { data.deref().get_ref().clone() } );
}
Poll::Pending
}
}
impl<Req: Clone + Debug> Request<Req> {
pub fn new() -> Self{
let data = Arc::new(Mutex::new(MaybeUninit::uninit()));
let data_ready = Arc::new(Mutex::new(false));
Self {data, data_ready}
}
pub fn send(&self, data: Req){
let mut gaurd = self.data.lock().unwrap();
unsafe { *gaurd.deref_mut().get_mut() = data; }
}
pub fn recv(&mut self) -> Option<Req>{
self.next()
}
}
impl<T: Clone + Debug> std::iter::Iterator for Request<T>{
type Item = T;
fn next(&mut self) -> Option<Self::Item>{
unsafe {
let ready_state = self.data_ready.lock().unwrap();
if *ready_state.deref() {
let data = self.data.lock().unwrap();
return Some( data.borrow().get_ref().clone() );
}
None
}
}
}
impl<T: Clone + Debug> fmt::Debug for Request<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let ready_state = self.data_ready.lock().unwrap();
let ready = *ready_state.deref();
let data = unsafe{
if ready {
let data = self.data.lock().unwrap();
Some(data.deref().get_ref().clone())
}else{
None
}
};
f.debug_struct("Response")
.field("ready", &ready)
.field("data", &data)
.finish()
}
}
#[derive(Clone)]
pub struct Response<T: Clone + Debug>{
data: Arc<Mutex<MaybeUninit<T>>>,
data_ready: Arc<Mutex<bool>>,
}
impl<Rsp: Clone + Debug> Response<Rsp> {
pub fn new() -> Self{
let data = Arc::new(Mutex::new(MaybeUninit::uninit()));
let data_ready = Arc::new(Mutex::new(false));
Self {data, data_ready}
}
pub fn send(&self, data: Rsp){
let mut gaurd = self.data.lock().unwrap();
unsafe { *gaurd.deref_mut().get_mut() = data; }
}
pub fn recv(&mut self) -> Option<Rsp>{
self.next()
}
}
impl<T: Clone + Debug> std::iter::Iterator for Response<T>{
type Item = T;
fn next(&mut self) -> Option<Self::Item>{
let ready_state = self.data_ready.lock().unwrap();
if *ready_state.deref() {
let data = self.data.lock().unwrap();
return Some( unsafe { data.deref().get_ref().clone() } );
}
None
}
}
impl<T: Clone + Debug> fmt::Debug for Response<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let ready_state = self.data_ready.lock().unwrap();
let ready = *ready_state.deref();
let data = unsafe{
if ready {
let data = self.data.lock().unwrap();
Some(data.deref().get_ref().clone())
}else{
None
}
};
f.debug_struct("Response")
.field("ready", &ready)
.field("data", &data)
.finish()
}
}
impl<Req: Clone + Debug> std::future::Future for Response<Req> {
type Output = Req;
fn poll(self: Pin<&mut Self>, _ctx: &mut Context) -> Poll<Self::Output>{
let ready_state = self.data_ready.lock().unwrap();
if *ready_state.deref() {
let data = self.data.lock().unwrap();
return Poll::Ready( unsafe { data.deref().get_ref().clone() } );
}
Poll::Pending
}
}
#[derive(Clone, Debug)]
pub struct Query<Req: Clone + Debug, Rsp: Clone + Debug>{
request: Request<Req>,
response: Response<Rsp>,
}
impl<Req: Clone + Debug, Rsp: Clone + Debug> Query<Req, Rsp>{
pub fn new() -> Self{
let request = Request::new();
let response = Response::new();
Self {request, response}
}
pub fn send_request(&self, data: Req){
self.request.send(data);
}
pub fn send_response(&self, data: Rsp){
self.response.send(data);
}
pub fn recv_request(&mut self) -> Option<Req>{
self.request.recv()
}
pub fn recv_response(&mut self) -> Option<Rsp>{
self.response.recv()
}
}
impl Default for Query {
fn default() -> Self{
Self::new()
}
}
impl<Req: Clone + Debug, Rsp: Clone + Debug> std::iter::Iterator for Query<Req, Rsp> {
type Item = Req;
fn next(&mut self) -> Option<Self::Item>{
self.request.next()
}
}