use std::collections::VecDeque;
pub trait StrRead {
fn peek_str(&self) -> Option<&str>;
fn is_empty(&self) -> bool {
self.peek_str().is_none()
}
}
pub trait RealStrRead: StrRead {
fn pop_str(&mut self) -> Option<&str>;
}
pub trait StringRead: StrRead {
fn pop_string(&mut self) -> Option<String>;
fn peek_mut_string(&mut self) -> Option<&mut String>;
fn map_string(&mut self, f: impl FnMut(&mut String)) {
self.peek_mut_string().map(f);
}
}
pub trait StrWrite<'a> {
fn push_str(&'a mut self, s: &'a str);
fn shift_str(&'a mut self, s: &'a str);
}
pub trait StringWrite {
fn push_string(&mut self, s: String);
fn shift_string(&mut self, s: String);
}
impl StrRead for String {
fn peek_str(&self) -> Option<&str> {
Some(self)
}
}
impl StringRead for String {
fn pop_string(&mut self) -> Option<String> {
Some(std::mem::take(self))
}
fn map_string(&mut self, mut f: impl FnMut(&mut String)) {
f(self);
}
fn peek_mut_string(&mut self) -> Option<&mut String> {
Some(self)
}
}
#[derive(Clone, Debug)]
pub struct StringReader<R: StringRead = String> {
pub queue: VecDeque<String>,
pub reader: Option<R>,
}
impl<R: StringRead> Default for StringReader<R> {
fn default() -> Self {
Self {
queue: Default::default(),
reader: None,
}
}
}
impl<R: StringRead> From<R> for StringReader<R> {
fn from(value: R) -> Self {
Self {
queue: Default::default(),
reader: Some(value),
}
}
}
impl<R: StringRead> From<VecDeque<String>> for StringReader<R> {
fn from(value: VecDeque<String>) -> Self {
Self {
queue: value,
reader: None,
}
}
}
impl<R: StringRead> StringReader<R> {
#[must_use]
pub fn new() -> Self {
Self::default()
}
}
impl<R: StringRead> StrRead for StringReader<R> {
fn peek_str(&self) -> Option<&str> {
(self.queue.front().map(|s| s.as_str()))
.or_else(|| self.reader.as_ref().map(|r| r.peek_str())?)
}
fn is_empty(&self) -> bool {
self.queue.is_empty() && self.reader.as_ref().map_or(true, |r| r.is_empty())
}
}
impl<R: StringRead> StringRead for StringReader<R> {
fn pop_string(&mut self) -> Option<String> {
(self.queue.pop_front()).or_else(|| self.reader.as_mut().map(|r| r.pop_string())?)
}
fn peek_mut_string(&mut self) -> Option<&mut String> {
(self.queue.front_mut()).or_else(|| self.reader.as_mut().map(|r| r.peek_mut_string())?)
}
}
impl<R: StringRead> std::io::Read for StringReader<R> {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
let mut l = buf.len();
let mut pos = 0;
while let Some(s) = self.peek_mut_string() {
let slen = s.len();
if slen > l {
buf[pos..].copy_from_slice(s[..l].as_bytes());
*s = s[l..].to_string();
return Ok(buf.len());
}
buf[pos..pos + slen].copy_from_slice(self.pop_string().unwrap().as_bytes());
pos += slen;
l -= slen;
}
Ok(pos)
}
}
impl<R: StringRead> std::io::BufRead for StringReader<R> {
fn fill_buf(&mut self) -> std::io::Result<&[u8]> {
if let Some(s) = self.peek_str() {
Ok(s.as_bytes())
} else if let Some(s) = self.reader.as_ref().and_then(|r| r.peek_str()) {
Ok(s.as_bytes())
} else {
Ok(&[])
}
}
fn consume(&mut self, amt: usize) {
use std::io::Read;
let mut buf: Vec<u8> = Vec::new();
(0..amt).for_each(|_| buf.push(0));
self.read(&mut buf).unwrap();
}
}
impl StrRead for str {
fn peek_str(&self) -> Option<&str> {
Some(self)
}
}
impl RealStrRead for str {
fn pop_str(&mut self) -> Option<&str> {
Some(self)
}
}
impl<R: StrRead + ?Sized> StrRead for Box<R> {
fn peek_str(&self) -> Option<&str> {
(**self).peek_str()
}
}
impl<R: RealStrRead + ?Sized> RealStrRead for Box<R> {
fn pop_str(&mut self) -> Option<&str> {
(**self).pop_str()
}
}
#[derive(Clone, Debug)]
pub struct StrReader<'a, R: RealStrRead = Box<str>> {
pub queue: VecDeque<&'a str>,
pub reader: Option<R>,
}
impl<'a, R: RealStrRead> Default for StrReader<'a, R> {
fn default() -> Self {
Self {
queue: Default::default(),
reader: None,
}
}
}
impl<'a, R: RealStrRead> From<R> for StrReader<'a, R> {
fn from(value: R) -> Self {
Self {
queue: Default::default(),
reader: Some(value),
}
}
}
impl<'a, R: RealStrRead> From<VecDeque<&'a str>> for StrReader<'a, R> {
fn from(value: VecDeque<&'a str>) -> Self {
Self {
queue: value,
reader: None,
}
}
}
impl<'a, R: RealStrRead> StrReader<'a, R> {
#[must_use]
pub fn new() -> Self {
Self::default()
}
}
impl<'a, R: RealStrRead> StrRead for StrReader<'a, R> {
fn peek_str(&self) -> Option<&str> {
(self.queue.front().copied()).or_else(|| self.reader.as_ref().and_then(|r| r.peek_str()))
}
fn is_empty(&self) -> bool {
self.queue.is_empty() && self.reader.as_ref().map_or(true, |r| r.is_empty())
}
}
impl<'a, R: RealStrRead> RealStrRead for StrReader<'a, R> {
fn pop_str(&mut self) -> Option<&str> {
self.queue
.pop_front()
.or_else(|| self.reader.as_mut().and_then(|r| r.pop_str()))
}
}
impl<'r, R: RealStrRead> StrWrite<'r> for StrReader<'r, R> {
fn push_str(&'r mut self, s: &'r str) {
self.queue.push_back(s);
}
fn shift_str(&'r mut self, s: &'r str) {
self.queue.push_front(s);
}
}
impl<R: StringRead> StringWrite for StringReader<R> {
fn push_string(&mut self, s: String) {
self.queue.push_back(s);
}
fn shift_string(&mut self, s: String) {
self.queue.push_front(s);
}
}