use crate::{
Character,
TextInput,
};
use pups_core::Input;
use std::marker::PhantomData;
pub struct Text<'a> {
buffer: &'a str,
byte_offset: usize,
}
impl<'a> Text<'a> {
fn from_string(string: &'a str) -> Self {
Self { buffer: string, byte_offset: 0 }
}
}
impl<'a> Input<'a> for Text<'a> {
type Item = char;
type Slice = &'a str;
fn advance(&self) {
if let Some (character) = self.peek() {
unsafe {
let mutable: *mut Self = self as *const Self as *mut Self;
(*mutable).byte_offset += character.length();
}
}
}
fn consume(&'a self, length: usize) -> Option<&'a str> {
let start: usize = self.save_cursor();
let mut slice_byte_count: usize = 0;
for _ in 0..length {
if let Some(character) = self.next() {
slice_byte_count += character.length();
} else { return None; }
}
let slice: &'a str = &self.buffer[start..start + slice_byte_count];
Some (slice)
}
fn next(&self) -> Option<Self::Item> {
if let Some (character) = self.peek() {
unsafe {
let mutable: *mut Self = self as *const Self as *mut Self;
(*mutable).byte_offset += character.length();
}
Some (character)
} else { None }
}
fn peek(&self) -> Option<Self::Item> {
char::next_in(&self.buffer[self.byte_offset..])
}
fn restore_cursor(&self, cursor: usize) {
unsafe {
let mutable: *mut Self = self as *const Self as *mut Self;
(*mutable).byte_offset = cursor;
}
}
fn save_cursor(&self) -> usize { self.byte_offset }
}
impl<'a> TextInput for Text<'a> {
fn starts_with(&self, string: &str) -> bool
{ self.buffer[self.byte_offset..].starts_with(string) }
fn skip_bytes(&mut self, byte_count: usize) { self.restore_cursor(self.byte_offset + byte_count) }
}