use crate::core::errors::{EditorError, Result};
use core::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Position {
pub offset: usize,
}
impl Position {
#[must_use]
pub const fn new(offset: usize) -> Self {
Self { offset }
}
#[must_use]
pub const fn start() -> Self {
Self { offset: 0 }
}
#[must_use]
pub const fn is_start(&self) -> bool {
self.offset == 0
}
#[must_use]
pub const fn advance(&self, bytes: usize) -> Self {
Self {
offset: self.offset.saturating_add(bytes),
}
}
#[must_use]
pub const fn retreat(&self, bytes: usize) -> Self {
Self {
offset: self.offset.saturating_sub(bytes),
}
}
}
impl Default for Position {
fn default() -> Self {
Self::start()
}
}
impl fmt::Display for Position {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.offset)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct LineColumn {
pub line: usize,
pub column: usize,
}
impl LineColumn {
pub fn new(line: usize, column: usize) -> Result<Self> {
if line == 0 || column == 0 {
return Err(EditorError::InvalidPosition { line, column });
}
Ok(Self { line, column })
}
#[must_use]
pub const fn start() -> Self {
Self { line: 1, column: 1 }
}
}
impl fmt::Display for LineColumn {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}:{}", self.line, self.column)
}
}