use std::sync::Arc;
use super::pty::{ConinWriter, ConoutReader, Pty};
use crate::backend::ConPtyBackend;
use crate::core::options::PtyOptions;
use crate::core::pipes::{create_sync_pipes, SyncPipes};
use crate::core::pseudocon::PseudoConsole;
use crate::core::session::Session as SessionCore;
use crate::error::{Error, Result};
use crate::size::Size;
#[derive(Debug, Clone, Default)]
pub(crate) struct PtyBuilder {
options: PtyOptions,
}
impl PtyBuilder {
#[must_use]
pub(crate) const fn size(mut self, size: Size) -> Self {
self.options.size = size;
self
}
#[must_use]
pub(crate) fn backend(mut self, backend: ConPtyBackend) -> Self {
self.options.backend = Some(backend);
self
}
#[must_use]
#[cfg(test)]
pub(crate) const fn inherit_cursor(mut self, inherit: bool) -> Self {
self.options.inherit_cursor = inherit;
self
}
#[must_use]
#[cfg(test)]
pub(crate) const fn eof_on_root_exit(mut self, eof: bool) -> Self {
self.options.eof_on_root_exit = eof;
self
}
pub(crate) fn build(self) -> Result<Pty> {
let backend = match self.options.backend {
Some(backend) => backend,
None => ConPtyBackend::resolve_default()?,
};
let SyncPipes {
conout_read,
conout_write,
conin_read,
conin_write,
} = create_sync_pipes().map_err(Error::create_console)?;
let console = PseudoConsole::new(
backend,
self.options.size,
conin_read,
conout_write,
self.options.inherit_cursor,
)
.map_err(Error::create_console)?;
let shared = Arc::clone(console.shared());
let inner = Arc::new(SessionCore::new(console, self.options.eof_on_root_exit));
Ok(Pty {
reader: ConoutReader::new(conout_read, shared),
writer: ConinWriter::new(conin_write, Arc::clone(&inner)),
inner,
})
}
}