use std::{cell::RefCell, error::Error, rc::Rc, time::Instant};
use crate::channel::{handler::Handler, pipeline_internal::PipelineInternal};
pub trait InboundPipeline<R> {
fn transport_active(&self);
fn transport_inactive(&self);
fn read(&self, msg: R);
fn handle_read_eof(&self);
fn handle_exception(&self, err: Box<dyn Error>);
fn handle_timeout(&self, now: Instant);
fn poll_timeout(&self, eto: &mut Instant);
fn poll_transmit(&self) -> Option<R>;
}
pub trait OutboundPipeline<R, W> {
fn write(&self, msg: W);
fn close(&self);
}
pub struct Pipeline<R, W> {
internal: RefCell<PipelineInternal<R, W>>,
}
impl<R: 'static, W: 'static> Default for Pipeline<R, W> {
fn default() -> Self {
Self::new()
}
}
impl<R: 'static, W: 'static> Pipeline<R, W> {
pub fn new() -> Self {
Self {
internal: RefCell::new(PipelineInternal::new()),
}
}
pub fn add_back(&self, handler: impl Handler + 'static) -> &Self {
{
let mut internal = self.internal.borrow_mut();
internal.add_back(handler);
}
self
}
pub fn add_front(&self, handler: impl Handler + 'static) -> &Self {
{
let mut internal = self.internal.borrow_mut();
internal.add_front(handler);
}
self
}
pub fn remove_back(&self) -> Result<&Self, std::io::Error> {
let result = {
let mut internal = self.internal.borrow_mut();
internal.remove_back()
};
match result {
Ok(()) => Ok(self),
Err(err) => Err(err),
}
}
pub fn remove_front(&self) -> Result<&Self, std::io::Error> {
let result = {
let mut internal = self.internal.borrow_mut();
internal.remove_front()
};
match result {
Ok(()) => Ok(self),
Err(err) => Err(err),
}
}
pub fn remove(&self, handler_name: &str) -> Result<&Self, std::io::Error> {
let result = {
let mut internal = self.internal.borrow_mut();
internal.remove(handler_name)
};
match result {
Ok(()) => Ok(self),
Err(err) => Err(err),
}
}
#[allow(clippy::len_without_is_empty)]
pub fn len(&self) -> usize {
let internal = self.internal.borrow();
internal.len()
}
pub fn update(self: Rc<Self>) -> Rc<Self> {
{
let internal = self.internal.borrow();
internal.finalize();
}
self
}
pub fn finalize(self) -> Rc<Self> {
let pipeline = Rc::new(self);
pipeline.update()
}
}
impl<R: 'static, W: 'static> InboundPipeline<R> for Pipeline<R, W> {
fn transport_active(&self) {
let internal = self.internal.borrow();
internal.transport_active();
}
fn transport_inactive(&self) {
let internal = self.internal.borrow();
internal.transport_inactive();
}
fn read(&self, msg: R) {
let internal = self.internal.borrow();
internal.handle_read(msg);
}
fn handle_read_eof(&self) {
let internal = self.internal.borrow();
internal.handle_read_eof();
}
fn handle_exception(&self, err: Box<dyn Error>) {
let internal = self.internal.borrow();
internal.handle_exception(err);
}
fn handle_timeout(&self, now: Instant) {
let internal = self.internal.borrow();
internal.handle_timeout(now);
}
fn poll_timeout(&self, eto: &mut Instant) {
let internal = self.internal.borrow();
internal.poll_timeout(eto);
}
fn poll_transmit(&self) -> Option<R> {
let internal = self.internal.borrow();
internal.poll_write()
}
}
impl<R: 'static, W: 'static> OutboundPipeline<R, W> for Pipeline<R, W> {
fn write(&self, msg: W) {
let internal = self.internal.borrow();
internal.write(msg);
}
fn close(&self) {
let internal = self.internal.borrow();
internal.handle_close();
}
}