use core::fmt;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Error {
message: String,
line: usize,
column: usize,
offset: usize,
path: Vec<String>,
}
impl Error {
pub(crate) fn parse(
message: impl Into<String>,
line: usize,
column: usize,
offset: usize,
) -> Self {
Error {
message: message.into(),
line,
column,
offset,
path: Vec::new(),
}
}
pub(crate) fn custom(message: impl Into<String>) -> Self {
Error {
message: message.into(),
line: 0,
column: 0,
offset: 0,
path: Vec::new(),
}
}
#[cfg_attr(not(feature = "serde"), allow(dead_code))]
pub(crate) fn prepend_key(&mut self, key: impl Into<String>) {
self.path.insert(0, key.into());
}
pub fn message(&self) -> &str {
&self.message
}
pub fn line(&self) -> usize {
self.line
}
pub fn column(&self) -> usize {
self.column
}
pub fn offset(&self) -> usize {
self.offset
}
pub fn has_position(&self) -> bool {
self.line != 0
}
pub fn key_path(&self) -> Option<String> {
if self.path.is_empty() {
None
} else {
Some(self.path.join("."))
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.has_position() {
write!(
f,
"TOML parse error at line {}, column {}: {}",
self.line, self.column, self.message
)
} else if let Some(path) = self.key_path() {
write!(f, "TOML error at `{path}`: {}", self.message)
} else {
f.write_str(&self.message)
}
}
}
impl std::error::Error for Error {}
#[cfg(feature = "serde")]
impl ::serde::de::Error for Error {
fn custom<T: fmt::Display>(message: T) -> Error {
Error::custom(message.to_string())
}
}
#[cfg(feature = "serde")]
impl ::serde::ser::Error for Error {
fn custom<T: fmt::Display>(message: T) -> Error {
Error::custom(message.to_string())
}
}