use core::cell::Cell;
use crate::BufferPtr;
#[derive(Default)]
pub struct BufferChain {
head_tail: Cell<Option<(BufferPtr, BufferPtr)>>,
}
impl BufferChain {
pub fn new() -> Self {
Self {
head_tail: Cell::new(None),
}
}
pub fn push(&self, buffer: BufferPtr) {
if let Some((prev_head, prev_tail)) = self.head_tail.get() {
let prev_tail_next = unsafe { prev_tail.swap_next(Some(buffer)) };
assert!(prev_tail_next.is_none());
self.head_tail.set(Some((prev_head, buffer)));
} else {
self.head_tail.set(Some((buffer, buffer)));
}
}
pub fn drain(&self) -> BufferChainDrain {
let head = self.head_tail.take().map(|(head, _)| head);
BufferChainDrain { head }
}
pub(crate) fn take_all(&self) -> Option<(BufferPtr, BufferPtr)> {
self.head_tail.take()
}
}
pub struct BufferChainDrain {
head: Option<BufferPtr>,
}
impl core::iter::Iterator for BufferChainDrain {
type Item = BufferPtr;
fn next(&mut self) -> Option<Self::Item> {
if let Some(buffer) = self.head {
self.head = unsafe { buffer.swap_next(None) };
return Some(buffer);
}
None
}
}