use std::fmt;
use std::cmp::{PartialOrd, Ord, Ordering};
#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct Position {
pub line: usize,
pub column: usize
}
impl PartialOrd for Position {
fn partial_cmp(&self, other: &Position) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Position {
fn cmp(&self, other: &Position) -> Ordering {
match self.line.cmp(&other.line) {
Ordering::Equal => self.column.cmp(&other.column),
ord => ord
}
}
}
impl Position {
pub fn new(line: usize, column: usize) -> Position {
Position {
line: line,
column: column
}
}
pub fn next_column(&self) -> Position {
Position {
line: self.line,
column: self.column+1
}
}
pub fn reset_column(&self) -> Position {
Position {
line: self.line,
column: 0
}
}
pub fn next_line(&self) -> Position {
Position {
line: self.line+1,
column: 0
}
}
pub fn next(&self, c: char) -> Position {
match c {
'\n' => self.next_line(),
'\r' => self.reset_column(),
'\t' => Position {
line: self.line,
column: (self.column/8)*8 + 8
},
c if c.is_control() => *self,
_ => self.next_column()
}
}
}
impl fmt::Display for Position {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "line {} column {}", self.line+1, self.column+1)
}
}
impl fmt::Debug for Position {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}:{}", self.line+1, self.column+1)
}
}