use std::fmt::Debug;
use std::fmt::Display;
use markdown::unist::Point as UnistPoint;
use markdown::unist::Position as UnistPosition;
use serde::Deserialize;
use serde::Serialize;
#[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize)]
pub struct Point {
pub line: usize,
pub column: usize,
pub offset: usize,
}
impl Point {
#[must_use]
pub fn new(line: usize, column: usize, offset: usize) -> Point {
Self {
line,
column,
offset,
}
}
pub fn advance_str(&mut self, text: &str) {
for byte in text.bytes() {
if byte == b'\n' {
self.line += 1;
self.column = 0;
self.offset += 1;
} else {
self.column += 1;
self.offset += 1;
}
}
}
pub fn advance(&mut self, text: impl Display) {
self.advance_str(&text.to_string());
}
}
impl From<UnistPoint> for Point {
fn from(point: UnistPoint) -> Self {
Self {
line: point.line,
column: point.column,
offset: point.offset,
}
}
}
impl Debug for Point {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}:{} ({})", self.line, self.column, self.offset)
}
}
#[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize)]
pub struct Position {
pub start: Point,
pub end: Point,
}
impl Position {
#[must_use]
pub fn new(
start_line: usize,
start_column: usize,
start_offset: usize,
end_line: usize,
end_column: usize,
end_offset: usize,
) -> Position {
Self {
start: Point::new(start_line, start_column, start_offset),
end: Point::new(end_line, end_column, end_offset),
}
}
pub fn from_point(point: Point) -> Self {
Self {
start: point,
end: point,
}
}
pub fn from_points(start: Point, end: Point) -> Self {
Self { start, end }
}
pub fn advance_start_str(&mut self, text: &str) {
self.start.advance_str(text);
}
pub fn advance_start(&mut self, text: impl Display) {
self.start.advance(text);
}
pub fn advance_end(&mut self, text: impl Display) {
self.end.advance(text);
}
}
impl From<UnistPosition> for Position {
fn from(position: UnistPosition) -> Self {
Self {
start: Point::from(position.start),
end: Point::from(position.end),
}
}
}
impl Debug for Position {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}:{}-{}:{} ({}-{})",
self.start.line,
self.start.column,
self.end.line,
self.end.column,
self.start.offset,
self.end.offset
)
}
}