use std::ops::Index;
use std::rc::Rc;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Position {
source: Rc<String>,
index: usize,
}
impl<T : std::fmt::Display> From<T> for Position {
fn from(value : T) -> Self {
let index = 0;
let source = Rc::from(value.to_string());
Position { source, index }
}
}
impl Iterator for Position {
type Item = char;
fn next(&mut self) -> Option<Self::Item> {
let character_maybe = self.source.chars().nth(self.index);
if character_maybe.is_some() { self.index += 1; }
character_maybe
}
}
impl Position {
pub fn column(&self) -> usize {
let mut column = 1;
for (i, c) in self.source.char_indices() {
if i >= self.index { break; }
else if c == '\n' { column = 1; }
else { column += 1; }
}
column
}
pub fn remainder(&self) -> &str {
&self.source[self.index..]
}
pub fn source(&self) -> &str {
&self.source
}
pub fn index(&self) -> usize {
self.index
}
pub fn line(&self) -> usize {
let mut line = 1;
for (i, c) in self.source.char_indices() {
if i >= self.index { break; }
else if c == '\n' { line += 1; }
}
line
}
}
impl PartialOrd for Position {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.index.partial_cmp(&other.index)
}
}
impl Ord for Position {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.index.cmp(&other.index)
}
}