#![no_std]
extern crate alloc;
mod channel;
mod discipline;
pub use discipline::{Event, LineDiscipline};
use alloc::sync::Arc;
use channel::Channel;
use core2::io::{Read, Result, Write};
#[derive(Clone)]
pub struct Tty {
master: Channel,
slave: Channel,
discipline: Arc<LineDiscipline>,
}
impl Default for Tty {
fn default() -> Self {
Self::new()
}
}
impl Tty {
pub fn new() -> Self {
Self {
master: Channel::new(),
slave: Channel::new(),
discipline: Default::default(),
}
}
pub fn master(&self) -> Master {
Master {
master: self.master.clone(),
slave: self.slave.clone(),
discipline: self.discipline.clone(),
}
}
pub fn slave(&self) -> Slave {
Slave {
master: self.master.clone(),
slave: self.slave.clone(),
discipline: self.discipline.clone(),
}
}
}
#[derive(Clone)]
pub struct Master {
master: Channel,
slave: Channel,
discipline: Arc<LineDiscipline>,
}
impl Master {
pub fn discipline(&self) -> Arc<LineDiscipline> {
self.discipline.clone()
}
pub fn read_byte(&self) -> Result<u8> {
self.master.receive()
}
pub fn read(&self, buf: &mut [u8]) -> Result<usize> {
self.master.receive_buf(buf)
}
pub fn try_read(&self, buf: &mut [u8]) -> Result<usize> {
self.master.try_receive_buf(buf)
}
pub fn write_byte(&self, byte: u8) -> Result<()> {
self.discipline
.process_input_byte(byte, &self.master, &self.slave)?;
Ok(())
}
pub fn write(&self, buf: &[u8]) -> Result<usize> {
self.discipline
.process_input_buf(buf, &self.master, &self.slave)?;
Ok(buf.len())
}
}
impl Read for Master {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let immutable: &Self = self;
immutable.read(buf)
}
}
impl Write for Master {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
let immutable: &Self = self;
immutable.write(buf)
}
fn flush(&mut self) -> core2::io::Result<()> {
todo!("do we flush canonical buffer?");
}
}
#[derive(Clone)]
pub struct Slave {
master: Channel,
slave: Channel,
discipline: Arc<LineDiscipline>,
}
impl Slave {
pub fn discipline(&self) -> Arc<LineDiscipline> {
self.discipline.clone()
}
pub fn read_byte(&self) -> Result<u8> {
self.slave.receive()
}
pub fn read(&self, buf: &mut [u8]) -> Result<usize> {
self.slave.receive_buf(buf)
}
pub fn try_read(&self, buf: &mut [u8]) -> Result<usize> {
self.slave.try_receive_buf(buf)
}
pub fn write_byte(&self, byte: u8) -> Result<()> {
self.discipline.process_output_byte(byte, &self.master)?;
Ok(())
}
pub fn write(&self, buf: &[u8]) -> Result<usize> {
self.discipline.process_output_buf(buf, &self.master)?;
Ok(buf.len())
}
}
impl Read for Slave {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let immutable: &Self = self;
immutable.read(buf)
}
}
impl Write for Slave {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
let immutable: &Self = self;
immutable.write(buf)
}
fn flush(&mut self) -> Result<()> {
Ok(())
}
}