use std::path::PathBuf;
use thiserror::Error;
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct FileLocation {
pub path: Option<PathBuf>,
pub line: Option<usize>,
pub column: Option<usize>,
}
impl FileLocation {
pub fn new(path: Option<PathBuf>, line: Option<usize>, column: Option<usize>) -> Self {
Self { path, line, column }
}
pub fn at_line(line: usize) -> Self {
Self {
path: None,
line: Some(line),
column: None,
}
}
}
impl std::fmt::Display for FileLocation {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match (&self.path, self.line, self.column) {
(Some(p), Some(l), Some(c)) => write!(f, "{}:{}:{}", p.display(), l, c),
(Some(p), Some(l), None) => write!(f, "{}:{}", p.display(), l),
(Some(p), None, _) => write!(f, "{}", p.display()),
(None, Some(l), Some(c)) => write!(f, "<input>:{}:{}", l, c),
(None, Some(l), None) => write!(f, "<input>:{}", l),
(None, None, _) => write!(f, "<input>"),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum ParseMode {
#[default]
Strict,
Permissive,
}
#[derive(Debug, Error)]
pub enum FormatError {
#[error("io: {0}")]
Io(#[from] std::io::Error),
#[error("format: {0}")]
Format(String),
#[error("unsupported: {0}")]
Unsupported(String),
#[error("{spec} at {location}: {message}")]
Located {
spec: &'static str,
location: FileLocation,
message: String,
},
}
impl FormatError {
pub fn located<M: Into<String>>(
spec: &'static str,
location: FileLocation,
message: M,
) -> Self {
Self::Located {
spec,
location,
message: message.into(),
}
}
}