use crate::errors::{error, nil};
use crate::types::{byte, int};
use std::io;
#[derive(Debug, Clone, Default)]
pub struct Buffer {
inner: Vec<u8>,
}
impl Buffer {
pub fn new() -> Self {
Buffer::default()
}
pub fn Bytes(&self) -> &[byte] {
&self.inner
}
pub fn String(&self) -> String {
String::from_utf8_lossy(&self.inner).into_owned()
}
pub fn Len(&self) -> int {
self.inner.len() as int
}
pub fn len(&self) -> usize {
self.inner.len()
}
pub fn Cap(&self) -> int {
self.inner.capacity() as int
}
pub fn Reset(&mut self) {
self.inner.clear();
}
pub fn Grow(&mut self, n: int) {
if n > 0 {
self.inner.reserve(n as usize);
}
}
pub fn Truncate(&mut self, n: int) {
self.inner.truncate(n as usize);
}
pub fn Write(&mut self, p: &[byte]) -> (int, error) {
self.inner.extend_from_slice(p);
(p.len() as int, nil)
}
pub fn WriteString(&mut self, s: &str) -> (int, error) {
self.inner.extend_from_slice(s.as_bytes());
(s.len() as int, nil)
}
pub fn WriteByte(&mut self, b: byte) -> error {
self.inner.push(b);
nil
}
}
impl io::Write for Buffer {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.inner.extend_from_slice(buf);
Ok(buf.len())
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
impl std::fmt::Display for Buffer {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", String::from_utf8_lossy(&self.inner))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn write_string_appends() {
let mut b = Buffer::new();
b.WriteString("hello ");
b.WriteString("world");
assert_eq!(b.String(), "hello world");
assert_eq!(b.Len(), 11);
}
#[test]
fn write_byte_appends() {
let mut b = Buffer::new();
b.WriteByte(b'X');
b.WriteByte(b'Y');
assert_eq!(b.String(), "XY");
}
#[test]
fn reset_clears_contents() {
let mut b = Buffer::new();
b.WriteString("data");
b.Reset();
assert_eq!(b.Len(), 0);
assert_eq!(b.String(), "");
}
#[test]
fn truncate_keeps_prefix() {
let mut b = Buffer::new();
b.WriteString("hello world");
b.Truncate(5);
assert_eq!(b.String(), "hello");
}
#[test]
fn fprintf_to_buffer() {
let mut b = Buffer::new();
let _ = crate::Fprintf!(&mut b, "n=%d %s", 42, "ok");
assert_eq!(b.String(), "n=42 ok");
}
#[test]
fn display_prints_contents() {
let mut b = Buffer::new();
b.WriteString("displayed");
assert_eq!(format!("{}", b), "displayed");
}
}