use std::cell::RefCell;
use std::io;
use std::process::Command;
use std::rc::Rc;
use std::time::Duration;
use crate::event::Event;
use crate::session::Backend;
struct State {
size: (u16, u16),
now: Duration,
output: String,
copies: Vec<String>,
}
pub struct PushBackend {
state: Rc<RefCell<State>>,
alternate_screen: bool,
}
#[derive(Clone)]
pub struct PushPort {
state: Rc<RefCell<State>>,
}
impl PushBackend {
pub fn new(columns: u16, rows: u16) -> PushBackend {
PushBackend {
state: Rc::new(RefCell::new(State {
size: (columns, rows),
now: Duration::ZERO,
output: String::new(),
copies: Vec::new(),
})),
alternate_screen: true,
}
}
#[must_use]
pub fn inline(mut self) -> PushBackend {
self.alternate_screen = false;
self
}
pub fn port(&self) -> PushPort {
PushPort {
state: Rc::clone(&self.state),
}
}
}
impl PushPort {
pub fn set_elapsed(&self, now: Duration) {
let mut state = self.state.borrow_mut();
state.now = state.now.max(now);
}
pub fn elapsed(&self) -> Duration {
self.state.borrow().now
}
pub fn take_output(&self) -> String {
std::mem::take(&mut self.state.borrow_mut().output)
}
pub fn take_copies(&self) -> Vec<String> {
std::mem::take(&mut self.state.borrow_mut().copies)
}
pub fn set_size(&self, columns: u16, rows: u16) {
self.state.borrow_mut().size = (columns, rows);
}
}
impl Backend for PushBackend {
fn size(&self) -> (u16, u16) {
self.state.borrow().size
}
fn read(&mut self, _timeout: Option<Duration>) -> io::Result<Option<Event>> {
Err(io::Error::new(
io::ErrorKind::Unsupported,
"a push backend is not read: drive the loop with EventLoop::step and pump",
))
}
fn write(&mut self, text: &str) -> io::Result<()> {
self.state.borrow_mut().output.push_str(text);
Ok(())
}
fn elapsed(&self) -> Duration {
self.state.borrow().now
}
fn handoff(&mut self, _command: &mut Command) -> io::Result<Option<i32>> {
Ok(None)
}
fn alternate_screen(&self) -> bool {
self.alternate_screen
}
fn clipboard(&self) -> Result<(), String> {
Ok(())
}
fn copy(&mut self, text: &str) -> io::Result<()> {
self.state.borrow_mut().copies.push(text.to_string());
Ok(())
}
}