use std::fmt::Write;
#[derive(Clone, Default)]
pub struct Buffer {
pub buffer: Vec<char>,
pub buffer_pos: usize,
}
impl Buffer {
pub fn new() -> Self {
Self { ..Self::default() }
}
pub fn insert(&mut self, c: char) {
self.buffer.insert(self.buffer_pos, c);
self.move_forward();
}
pub fn insert_str(&mut self, s: &str) {
s.chars().for_each(|c| self.insert(c));
}
pub fn set_buffer_pos(&mut self, pos: usize) {
self.buffer_pos = pos;
}
pub fn remove_current_char(&mut self) -> Option<char> {
if !self.is_empty() && self.buffer_pos < self.buffer.len() {
let character = self.buffer.remove(self.buffer_pos);
Some(character)
} else {
None
}
}
pub fn next_char(&self) -> Option<&char> {
self.buffer.get(self.buffer_pos + 1)
}
pub fn current_char(&self) -> Option<&char> {
self.buffer.get(self.buffer_pos)
}
pub fn previous_char(&self) -> Option<&char> {
if self.buffer_pos > 0 {
self.buffer.get(self.buffer_pos - 1)
} else {
None
}
}
pub fn move_forward(&mut self) {
self.buffer_pos += 1;
}
pub fn move_backward(&mut self) {
if self.buffer_pos != 0 {
self.buffer_pos -= 1;
}
}
pub fn clear(&mut self) {
self.buffer.clear();
self.buffer_pos = 0;
}
pub fn len(&self) -> usize {
self.buffer.len()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn is_at_string_line_start(&self) -> bool {
self.is_empty()
|| self.buffer[..self.buffer_pos]
.rsplitn(2, |d| d == &'\n')
.next()
.unwrap_or_default()
.iter()
.all(|c| c.is_whitespace())
}
pub fn is_at_start(&self) -> bool {
self.buffer_pos == 0
}
pub fn is_at_end(&self) -> bool {
self.buffer_pos == self.buffer.len()
}
pub fn goto_start(&mut self) {
self.buffer_pos = 0;
}
pub fn goto_end(&mut self) {
self.buffer_pos = self.buffer.len();
}
pub fn _push_str(&mut self, str: &str) {
self.buffer.extend(str.chars());
self.buffer_pos = self.buffer.len();
}
pub fn get(&self, idx: usize) -> Option<&char> {
self.buffer.get(idx)
}
pub fn _last(&self) -> Option<&char> {
self.buffer.last()
}
pub fn iter(&self) -> impl Iterator<Item = &char> {
self.buffer.iter()
}
pub fn take(&mut self) -> Vec<char> {
let buffer = std::mem::take(&mut self.buffer);
self.clear();
self.goto_start();
buffer
}
}
impl std::fmt::Display for Buffer {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for c in self.buffer.iter() {
f.write_char(*c)?;
}
Ok(())
}
}
impl From<&str> for Buffer {
fn from(string: &str) -> Self {
Self {
buffer: string.chars().collect(),
buffer_pos: 0,
}
}
}
impl From<String> for Buffer {
fn from(string: String) -> Self {
Self {
buffer: string.chars().collect(),
buffer_pos: 0,
}
}
}
impl From<Vec<char>> for Buffer {
fn from(buffer: Vec<char>) -> Self {
Self {
buffer,
buffer_pos: 0,
}
}
}
impl FromIterator<char> for Buffer {
fn from_iter<I: IntoIterator<Item = char>>(iter: I) -> Buffer {
let mut buffer = Buffer::new();
for c in iter {
buffer.buffer.push(c);
}
buffer
}
}