#![cfg(feature = "engate")]
use std::sync::Arc;
use std::sync::mpsc;
use engate_attach::{Consumer, Producer};
use engate_types::AttachError;
use tear_types::PaneId;
use tear_types::engate_wrap::PaneSnapshotWrap;
use crate::inproc::InProcess;
pub struct PaneProducer {
pub inproc: Arc<InProcess>,
pub pane: PaneId,
}
impl PaneProducer {
#[must_use]
pub fn new(inproc: Arc<InProcess>, pane: PaneId) -> Self {
Self { inproc, pane }
}
}
impl Producer for PaneProducer {
type Item = Vec<u8>;
type Snap = PaneSnapshotWrap;
fn snapshot(&self) -> Result<Self::Snap, AttachError> {
self.inproc
.pane_snapshot(self.pane)
.map(PaneSnapshotWrap)
.map_err(|e| AttachError::SnapshotFailed(e.to_string()))
}
fn subscribe(&self) -> Result<mpsc::Receiver<Self::Item>, AttachError> {
self.inproc
.subscribe_pane_bytes(self.pane)
.map_err(|e| AttachError::SubscribeFailed(e.to_string()))
}
}
pub fn replay_via_consume<C>(consumer: &mut C, snap: PaneSnapshotWrap)
where
C: Consumer<Item = Vec<u8>, Snap = PaneSnapshotWrap>,
{
let bytes = snap.to_ansi();
consumer.consume(bytes);
}
#[cfg(test)]
mod tests {
use super::*;
use tear_types::{MultiplexerControl, SessionSource};
#[test]
fn pane_producer_snapshot_and_subscribe() {
let inproc = Arc::new(InProcess::new());
let sid = inproc
.new_session_with_source_and_size(
"engate-test",
"/bin/sh",
SessionSource::Human,
(80, 24),
)
.expect("spawn session");
let pane = inproc.with_registry(|r| {
r.sessions
.get(&sid)
.and_then(|s| s.panes.keys().next().copied())
.expect("pane")
});
let producer = PaneProducer::new(inproc, pane);
let snap = producer.snapshot().expect("snapshot");
assert_eq!(snap.0.cols, 80);
assert_eq!(snap.0.rows, 24);
let _rx = producer.subscribe().expect("subscribe");
}
}