use std::fmt::{Debug, Display}; #[derive(Debug, Clone, PartialEq, PartialOrd, Ord, Eq)] pub struct Loc { file: String, line: usize, col: usize, } #[allow(dead_code)] impl Loc { pub fn new(s: impl ToString, line: usize, col: usize) -> Self { Self { file: s.to_string(), line, col } } fn file(&self) -> &String { &self.file } fn line(&self) -> usize { self.line } fn col(&self) -> usize { self.col } } #[derive(Debug, Clone)] pub struct LocBox { inner: T, loc: Loc } impl LocBox { pub fn new(loc: &Loc, inner: T) -> Self { Self { loc: loc.clone(), inner } } pub fn inner(&self) -> &T { &self.inner } pub fn inner_mut(&mut self) -> &mut T { &mut self.inner } pub fn loc(&self) -> &Loc { &self.loc } } impl Display for Loc { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}:{}:{}", self.file, self.line, self.col) } } impl Default for Loc { fn default() -> Self { Self { line: 1, col: 1, file: Default::default() } } } pub trait LocIncr { fn inc_line(&mut self); fn inc_col(&mut self); } impl LocIncr for Loc { fn inc_line(&mut self) { self.line += 1; self.col = 1; } fn inc_col(&mut self) { self.col += 1; } }