use std::collections::VecDeque;
#[derive(Debug, Clone)]
pub struct DraftBuffer {
chars: VecDeque<char>,
}
impl DraftBuffer {
pub fn new() -> Self {
Self {
chars: VecDeque::new(),
}
}
pub fn with_capacity(capacity: usize) -> Self {
Self {
chars: VecDeque::with_capacity(capacity),
}
}
pub fn from_string(s: &str) -> Self {
let chars: VecDeque<char> = s.chars().collect();
Self { chars }
}
pub fn insert(&mut self, ch: char) {
self.chars.push_back(ch);
}
pub fn delete(&mut self) -> Option<char> {
self.chars.pop_back()
}
pub fn len(&self) -> usize {
self.chars.len()
}
pub fn is_empty(&self) -> bool {
self.chars.is_empty()
}
pub fn as_str(&self) -> String {
self.chars.iter().collect()
}
pub fn as_bytes(&self) -> Vec<u8> {
self.as_str().into_bytes()
}
pub fn clear(&mut self) {
self.chars.clear();
}
pub fn truncate(&mut self, len: usize) {
if len < self.chars.len() {
self.chars.truncate(len);
}
}
}
impl Default for DraftBuffer {
fn default() -> Self {
Self::new()
}
}
impl From<String> for DraftBuffer {
fn from(s: String) -> Self {
Self::from_string(&s)
}
}
impl From<&str> for DraftBuffer {
fn from(s: &str) -> Self {
Self::from_string(s)
}
}
impl std::fmt::Display for DraftBuffer {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.as_str())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new() {
let buffer = DraftBuffer::new();
assert_eq!(buffer.len(), 0);
assert!(buffer.is_empty());
assert_eq!(buffer.as_str(), "");
}
#[test]
fn test_insert() {
let mut buffer = DraftBuffer::new();
buffer.insert('a');
buffer.insert('b');
buffer.insert('c');
assert_eq!(buffer.len(), 3);
assert_eq!(buffer.as_str(), "abc");
}
#[test]
fn test_delete() {
let mut buffer = DraftBuffer::from_string("test");
assert_eq!(buffer.delete(), Some('t'));
assert_eq!(buffer.as_str(), "tes");
assert_eq!(buffer.delete(), Some('s'));
assert_eq!(buffer.as_str(), "te");
assert_eq!(buffer.len(), 2);
}
#[test]
fn test_delete_empty() {
let mut buffer = DraftBuffer::new();
assert_eq!(buffer.delete(), None);
}
#[test]
fn test_from_str() {
let buffer = DraftBuffer::from_string("hello");
assert_eq!(buffer.len(), 5);
assert_eq!(buffer.as_str(), "hello");
}
#[test]
fn test_clear() {
let mut buffer = DraftBuffer::from_string("test");
buffer.clear();
assert!(buffer.is_empty());
assert_eq!(buffer.as_str(), "");
}
#[test]
fn test_truncate() {
let mut buffer = DraftBuffer::from_string("hello");
buffer.truncate(3);
assert_eq!(buffer.as_str(), "hel");
assert_eq!(buffer.len(), 3);
}
#[test]
fn test_truncate_longer() {
let mut buffer = DraftBuffer::from_string("hi");
buffer.truncate(10);
assert_eq!(buffer.as_str(), "hi");
assert_eq!(buffer.len(), 2);
}
#[test]
fn test_unicode() {
let mut buffer = DraftBuffer::new();
buffer.insert('π');
buffer.insert('δΈ');
buffer.insert('η');
assert_eq!(buffer.len(), 3);
assert_eq!(buffer.as_str(), "πδΈη");
assert_eq!(buffer.delete(), Some('η'));
assert_eq!(buffer.as_str(), "πδΈ");
}
#[test]
fn test_as_bytes() {
let buffer = DraftBuffer::from_string("test");
assert_eq!(buffer.as_bytes(), b"test");
}
#[test]
fn test_display() {
let buffer = DraftBuffer::from_string("test");
assert_eq!(format!("{}", buffer), "test");
}
#[test]
fn test_from_string() {
let buffer = DraftBuffer::from(String::from("hello"));
assert_eq!(buffer.as_str(), "hello");
}
#[test]
fn test_with_capacity() {
let buffer = DraftBuffer::with_capacity(100);
assert!(buffer.is_empty());
}
#[test]
fn test_incremental_typing() {
let mut buffer = DraftBuffer::new();
for ch in "hello".chars() {
buffer.insert(ch);
}
assert_eq!(buffer.as_str(), "hello");
buffer.delete();
buffer.delete();
assert_eq!(buffer.as_str(), "hel");
buffer.insert('p');
assert_eq!(buffer.as_str(), "help");
}
}