use crate::buffer::Buffer;
use anyhow::Result;
use crossterm::event::{Event, KeyCode, read};
macro_rules! unwrap_or_return {
( $e:expr ) => {
match $e {
Some(x) => x,
None => return,
}
};
}
macro_rules! unwrap_or_break {
( $e:expr ) => {
match $e {
Some(x) => x,
None => break,
}
};
}
pub trait SplitOnce<T> {
fn split_once_a<F>(&self, pred: F) -> Option<(&[T], &[T])>
where
F: FnMut(&T) -> bool;
}
impl<T> SplitOnce<T> for [T] {
#[inline]
fn split_once_a<F>(&self, pred: F) -> Option<(&[T], &[T])>
where
F: FnMut(&T) -> bool,
{
let index = self.iter().position(pred)?;
Some((&self[..index], &self[index + 1..]))
}
}
pub fn is_symbol(c: char) -> bool {
"$`\'\":;~()\\+-=$#^[&]*<@%!{|}>/?.,".contains(c)
}
pub fn on_next_input(buffer: &mut Buffer, closure: fn(KeyCode, &mut Buffer)) -> Result<()> {
loop {
if let Event::Key(event) = read()? {
closure(event.code, buffer);
break;
}
}
Ok(())
}
pub fn last_char(str: &str) -> char {
str.chars().last().unwrap()
}
pub const fn count_line(str: &str) -> u16 {
let bytes = str.as_bytes();
let mut i = 0;
let mut len_lines = 0;
while i < bytes.len() {
if bytes[i] == b'\n' {
len_lines += 1;
}
i += 1;
}
len_lines
}
pub const fn count_longest_line(str: &str) -> u16 {
let mut longest_line = 0;
let mut curr_line = 0;
let bytes = str.as_bytes();
let mut i = 0;
while i < bytes.len() {
if bytes[i] == b'\n' {
if curr_line > longest_line {
longest_line = curr_line;
}
curr_line = 0;
} else {
curr_line += 1;
}
i += 1;
}
longest_line
}