trapeze 0.7.1

A rust implementation of ttrpc
Documentation
use std::future::Future;
use std::io::{Error as IoError, ErrorKind, Result as IoResult};
use std::ops::Deref;
use std::sync::Arc;
use std::task::{ready, Poll};

use futures::future::Aborted;
use futures::FutureExt as _;
use tokio::sync::Notify;
use tokio::task::JoinHandle;

use crate::server::controller::ServerController;

pub struct ServerHandle {
    pub(super) controller: ServerController,
    pub(super) handle: JoinHandle<Result<IoResult<()>, Aborted>>,
}

impl ServerHandle {
    pub fn controller(&self) -> ServerController {
        self.controller.clone()
    }
}

impl Drop for ServerHandle {
    fn drop(&mut self) {
        self.controller.terminate();
    }
}

impl Deref for ServerHandle {
    type Target = ServerController;

    fn deref(&self) -> &Self::Target {
        &self.controller
    }
}

impl Future for ServerHandle {
    type Output = IoResult<()>;
    fn poll(
        mut self: std::pin::Pin<&mut Self>,
        cx: &mut std::task::Context<'_>,
    ) -> std::task::Poll<Self::Output> {
        match ready!(self.handle.poll_unpin(cx)) {
            Ok(Ok(res)) => Poll::Ready(res),
            _ => Poll::Ready(Err(IoError::new(
                ErrorKind::Interrupted,
                "TTRPC server terminated abruptly",
            ))),
        }
    }
}

impl ServerHandle {
    pub(super) fn spawn<F: Future<Output = IoResult<()>> + Send + 'static>(
        fut_fn: impl Send + 'static + FnOnce(ServerController, Arc<Notify>) -> F,
    ) -> Self {
        let (controller, task) = ServerController::control(fut_fn);
        let handle = tokio::spawn(task);
        ServerHandle { controller, handle }
    }
}