evolution_parser/
trimmer.rsuse log::warn;
use padder::{Alignment, Symbol};
use std::slice::Iter;
pub trait Trimmer {}
pub type TrimmerRef = Box<dyn Trimmer>;
pub struct TextTrimmer {
alignment: Alignment,
symbol: char,
}
impl TextTrimmer {
pub fn new(alignment: Alignment, symbol: Symbol) -> Self {
Self {
alignment,
symbol: symbol.into(),
}
}
pub fn find_byte_indices(&self, bytes: &[u8], n_runes: usize) -> usize {
let mut utf8_byte_unit: usize = 1;
let mut n_bytes_read: usize = 0;
let mut n_found_runes: usize = 0;
let mut iterator: Iter<u8> = bytes.iter();
while n_found_runes < n_runes {
let byte: u8 = match iterator.nth(utf8_byte_unit - 1) {
Some(b) => *b,
None => break,
};
utf8_byte_unit = match byte {
byte if byte >> 7 == 0 => 1,
byte if byte >> 5 == 0b110 => 2,
byte if byte >> 4 == 0b1110 => 3,
byte if byte >> 3 == 0b11110 => 4,
_ => panic!("Couldn't parse byte slice, invalid UTF-8 sequence!"),
};
n_found_runes += 1;
n_bytes_read += utf8_byte_unit;
}
if n_found_runes != n_runes {
warn!("Read the entire byte slice but did not find enough runes...");
}
n_bytes_read
}
pub fn trim<'a>(&self, text: &'a str) -> &'a str {
match self.alignment {
Alignment::Left => text.trim_end_matches::<char>(self.symbol),
Alignment::Right => text.trim_start_matches::<char>(self.symbol),
Alignment::Center => text.trim_matches::<char>(self.symbol),
}
}
}
impl Trimmer for TextTrimmer {}
pub struct IntTrimmer {}
impl IntTrimmer {
pub fn new() -> Self {
Self {}
}
pub fn find_byte_indices(&self, bytes: &[u8], n_runes: usize) -> (usize, usize, usize) {
let mut utf8_byte_unit: usize = 1;
let mut n_bytes_read: usize = 0;
let mut n_found_runes: usize = 0;
let mut iterator: Iter<u8> = bytes.iter();
let mut has_found_start_of_number: bool = false;
let mut has_found_all_number_bytes: bool = false;
let mut start_byte_idx: usize = 0;
let mut stop_byte_idx: usize = 0;
while n_found_runes < n_runes {
let byte: u8 = match iterator.nth(utf8_byte_unit - 1) {
Some(b) => *b,
None => break,
};
n_bytes_read += utf8_byte_unit;
utf8_byte_unit = match byte {
byte if byte >> 7 == 0 => 1,
byte if byte >> 5 == 0b110 => 2,
byte if byte >> 4 == 0b1110 => 3,
byte if byte >> 3 == 0b11110 => 4,
_ => panic!("Couldn't parse byte slice, invalid UTF-8 sequence!"),
};
if !has_found_all_number_bytes {
if let 48..=57 = byte {
if !has_found_start_of_number {
start_byte_idx = n_bytes_read - utf8_byte_unit;
has_found_start_of_number = true;
}
if n_found_runes + 1 == n_runes {
stop_byte_idx = 1 + n_bytes_read - utf8_byte_unit;
has_found_all_number_bytes = true;
}
} else {
if has_found_start_of_number {
stop_byte_idx = n_bytes_read - utf8_byte_unit;
has_found_all_number_bytes = true;
}
}
}
if !has_found_start_of_number && (byte == 45) {
start_byte_idx = n_bytes_read - utf8_byte_unit;
has_found_start_of_number = true;
}
n_found_runes += 1;
}
(start_byte_idx, stop_byte_idx, n_bytes_read)
}
}
impl Trimmer for IntTrimmer {}
pub struct FloatTrimmer {
alignment: Alignment,
symbol: char,
}
impl FloatTrimmer {
pub fn new(alignment: Alignment, symbol: Symbol) -> Self {
Self {
alignment,
symbol: symbol.into(),
}
}
pub fn find_byte_indices(&self, bytes: &[u8], n_runes: usize) -> usize {
let mut utf8_byte_unit: usize = 1;
let mut n_bytes: usize = 0;
let mut found_runes: usize = 0;
let mut iterator: Iter<u8> = bytes.iter();
while found_runes < n_runes {
let byte: u8 = match iterator.nth(utf8_byte_unit - 1) {
Some(b) => *b,
None => break,
};
utf8_byte_unit = match byte {
byte if byte >> 7 == 0 => 1,
byte if byte >> 5 == 0b110 => 2,
byte if byte >> 4 == 0b1110 => 3,
byte if byte >> 3 == 0b11110 => 4,
_ => panic!("Couldn't parse byte slice, invalid UTF-8 sequence!"),
};
found_runes += 1;
n_bytes += utf8_byte_unit;
}
if found_runes != n_runes {
warn!("Read the entire byte slice but did not find enough runes...");
}
n_bytes
}
pub fn trim<'a>(&self, text: &'a str) -> &'a str {
match self.alignment {
Alignment::Left => text.trim_end_matches::<char>(self.symbol),
Alignment::Right => text.trim_start_matches::<char>(self.symbol),
Alignment::Center => text.trim_matches::<char>(self.symbol),
}
}
}
impl Trimmer for FloatTrimmer {}