86 lines
2.0 KiB
Rust
86 lines
2.0 KiB
Rust
use std::borrow::Cow;
|
|
use std::cell::RefCell;
|
|
use std::io;
|
|
|
|
#[derive(Eq, Debug)]
|
|
pub struct IOList {
|
|
chunks: RefCell<Vec<Vec<u8>>>,
|
|
len: usize,
|
|
}
|
|
|
|
impl IOList {
|
|
pub fn new() -> Self {
|
|
IOList {
|
|
chunks: RefCell::new(Vec::new()),
|
|
len: 0,
|
|
}
|
|
}
|
|
|
|
fn rightmost_chunk(&mut self) -> &mut Vec<u8> {
|
|
let cs = self.chunks.get_mut();
|
|
if cs.is_empty() {
|
|
cs.push(Vec::new());
|
|
}
|
|
cs.last_mut().unwrap()
|
|
}
|
|
|
|
fn consolidate(&self) {
|
|
if self.chunks.borrow().len() != 1 {
|
|
let bs = self.chunks.replace(Vec::new()).concat();
|
|
self.chunks.borrow_mut().push(bs);
|
|
}
|
|
}
|
|
|
|
pub fn len(&mut self) -> usize {
|
|
self.len
|
|
}
|
|
|
|
pub fn write(&mut self, b: u8) {
|
|
self.rightmost_chunk().push(b);
|
|
self.len += 1;
|
|
}
|
|
|
|
#[inline(always)]
|
|
pub fn write_all(&mut self, cow: Cow<'_, [u8]>) {
|
|
self.len += cow.len();
|
|
match cow {
|
|
Cow::Borrowed(bs) => self.chunks.get_mut().push(bs.to_owned()),
|
|
Cow::Owned(bs) => self.chunks.get_mut().push(bs),
|
|
}
|
|
}
|
|
|
|
pub fn append(&mut self, mut iol: IOList) {
|
|
self.len += iol.len();
|
|
self.chunks.get_mut().append(&mut iol.chunks.take());
|
|
}
|
|
|
|
pub fn write_to<W: io::Write>(self, mut w: W) -> io::Result<()> {
|
|
for chunk in self.chunks.take() {
|
|
w.write_all(&chunk)?;
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq for IOList {
|
|
fn eq(&self, other: &Self) -> bool {
|
|
self.consolidate();
|
|
other.consolidate();
|
|
self.chunks.borrow().last().unwrap() == other.chunks.borrow().last().unwrap()
|
|
}
|
|
}
|
|
|
|
impl std::cmp::Ord for IOList {
|
|
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
|
self.consolidate();
|
|
other.consolidate();
|
|
self.chunks.borrow().last().unwrap().cmp(other.chunks.borrow().last().unwrap())
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialOrd for IOList {
|
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
|
Some(self.cmp(other))
|
|
}
|
|
}
|