1use std::fmt::{self, Display, Formatter};
2
3use crate::loader::SourceTrace;
4
5#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
6pub struct UnknownField {
8 pub path: String,
10 pub source: Option<SourceTrace>,
12 pub suggestion: Option<String>,
14}
15
16impl UnknownField {
17 #[must_use]
19 pub fn new(path: impl Into<String>) -> Self {
20 Self {
21 path: path.into(),
22 source: None,
23 suggestion: None,
24 }
25 }
26
27 #[must_use]
29 pub fn with_source(mut self, source: Option<SourceTrace>) -> Self {
30 self.source = source;
31 self
32 }
33
34 #[must_use]
36 pub fn with_suggestion(mut self, suggestion: Option<String>) -> Self {
37 self.suggestion = suggestion;
38 self
39 }
40}
41
42impl Display for UnknownField {
43 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
44 write!(f, "unknown field `{}`", self.path)?;
45 if let Some(source) = &self.source {
46 write!(f, " from {source}")?;
47 }
48 if let Some(suggestion) = &self.suggestion {
49 write!(f, "; did you mean `{suggestion}`?")?;
50 }
51 Ok(())
52 }
53}
54
55#[derive(Debug, Clone, Copy, PartialEq, Eq)]
56pub struct LineColumn {
58 pub line: usize,
60 pub column: usize,
62}
63
64impl Display for LineColumn {
65 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
66 write!(f, "line {}, column {}", self.line, self.column)
67 }
68}