use crate::error::ErrorCode;
pub trait IByteStream {
fn peek_byte(&mut self) -> Option<u8>;
fn read_byte(&mut self) -> Option<u8>;
fn advance(&mut self);
fn has_more(&mut self) -> bool;
}
pub trait IByteReader: IByteStream {}
impl<T: IByteStream + ?Sized> IByteReader for T {}
pub trait IByteWriter {
fn write_byte(&mut self, byte: u8) -> Result<(), ErrorCode>;
fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), ErrorCode>;
}
pub trait ICharStream {
fn next(&mut self);
fn current(&mut self) -> Option<char>;
fn more(&mut self) -> bool;
}
pub trait ICharReader: ICharStream {}
impl<T: ICharStream + ?Sized> ICharReader for T {}
pub trait ISource {
fn next(&mut self);
fn current(&mut self) -> Option<char>;
fn more(&mut self) -> bool;
fn reset(&mut self);
}
pub trait IRewindable {
fn reset(&mut self);
}
pub trait IPositionAware {
fn position(&self) -> usize;
}
pub trait ILocationAware {
fn line(&self) -> usize;
fn column(&self) -> usize;
}
pub trait IFlushable {
fn flush(&mut self) -> Result<(), ErrorCode>;
}
pub trait ITailInspectable {
fn last_byte(&self) -> Option<u8>;
}
pub trait IClearable {
fn clear(&mut self);
}
pub trait IDestination {
fn add_byte(&mut self, byte: u8);
fn add_bytes(&mut self, bytes: &str);
fn clear(&mut self);
fn last(&self) -> Option<u8>;
}
pub trait IIndentationAware {
fn get_current_indent_level(&self) -> usize;
fn is_indent_whitespace(&self, c: char) -> bool {
c == ' ' || c == '\t'
}
fn is_whitespace(&self, c: char) -> bool {
c == ' ' || c == '\t'
}
fn is_tab(&self, c: char) -> bool {
c == '\t'
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
pub struct SaveState {
pub pos: u64,
pub current_byte: Option<u8>,
pub column: usize,
pub line: usize,
}
pub trait IStatefulStream {
fn save_state(&mut self) -> SaveState;
fn restore_state(&mut self, state: SaveState);
}
pub trait ILineReader: ICharStream {
fn read_line(&mut self) -> Option<alloc::string::String> {
let mut line = alloc::string::String::new();
if self.read_line_into(&mut line) {
Some(line)
} else {
None
}
}
fn read_line_into(&mut self, buf: &mut alloc::string::String) -> bool;
fn lines(&mut self) -> LineIter<'_, Self>
where
Self: Sized,
{
LineIter::new(self)
}
}
pub struct LineIter<'a, R: ?Sized> {
reader: &'a mut R,
}
impl<'a, R: ILineReader + ?Sized> LineIter<'a, R> {
pub fn new(reader: &'a mut R) -> Self {
Self { reader }
}
}
impl<'a, R: ILineReader + ?Sized> Iterator for LineIter<'a, R> {
type Item = alloc::string::String;
fn next(&mut self) -> Option<Self::Item> {
self.reader.read_line()
}
}