use std::{
fmt::{Display, Debug},
str::FromStr
};
use crate::InsertPosition;
#[derive(PartialEq, Eq)]
pub(crate) struct TextPosition {
line: usize,
col: usize,
}
impl TextPosition {
pub fn new(line: usize, col: usize) -> Self {
assert_ne!(line, 0);
assert!(!(line == 1 && col == 0));
TextPosition { line, col }
}
pub fn line(&self) -> usize { self.line }
pub fn col(&self) -> usize { self.col }
pub fn insert_pos_left(&self) -> InsertPosition {
assert_ne!(self.col, 0);
InsertPosition::new(self.line, self.col-1)
}
pub fn insert_pos_right(&self) -> InsertPosition {
InsertPosition::new(self.line, self.col)
}
}
impl Display for TextPosition {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}:{}", self.line(), self.col())
}
}
impl Debug for TextPosition {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self)
}
}
impl FromStr for TextPosition {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
let (line_str, col_str) = s.trim().split_once(':').ok_or(())?;
let line: usize = line_str.parse().map_err(|_| ())?;
let col: usize = col_str.parse().map_err(|_| ())?;
if line == 0 { return Err(()); }
if line == 1 && col == 0 { return Err(()); }
Ok(TextPosition::new(line, col))
}
}