Skip to content

Commit

Permalink
Make pretty miette errors work
Browse files Browse the repository at this point in the history
  • Loading branch information
ysthakur committed Dec 25, 2023
1 parent 060ba39 commit a7665d1
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 20 deletions.
15 changes: 11 additions & 4 deletions src/parse_deser/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,25 @@ pub enum Error {
#[error("{file_path} has no extension")]
#[diagnostic(code(gen_completions::deser::no_ext), url(docsrs))]
NoExtension { file_path: String },

#[error("{file_path} has an unrecognizable extension")]
#[diagnostic(code(gen_completions::deser::unrecognizable_ext), url(docsrs))]
UnrecognizableExtension { file_path: String },
#[error("error encountered while reading {file_path}")]

#[error("Error encountered while reading {file_path}")]
#[diagnostic(code(gen_completions::deser::io_error), url(docsrs))]
Io {
file_path: String,
#[source]
source: io::Error,
},
#[error("error encountered while deserializing {file_path}")]
#[diagnostic(code(gen_completions::deser::deser_error), url(docsrs))]

#[error("Error encountered while deserializing {file_path}")]
Deser {
file_path: String,
#[source]
#[source_code]
text: String,
#[diagnostic_source]
source: DeserError,
},
}
Expand All @@ -34,8 +38,11 @@ pub enum Error {
pub enum DeserError {
#[error(transparent)]
Json(#[from] serde_json::Error),

#[error(transparent)]
#[diagnostic()]
Yaml(#[from] serde_yaml::Error),

#[error(transparent)]
#[diagnostic(transparent)]
Kdl(#[from] KdlDeserError),
Expand Down
54 changes: 38 additions & 16 deletions src/parse_deser/kdl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,39 @@ use crate::{ArgType, CommandInfo, Flag};
#[derive(Debug, Diagnostic, Error)]
pub enum KdlDeserError {
#[error(transparent)]
#[diagnostic(transparent)]
SyntaxError(#[from] kdl::KdlError),

#[error("file was empty, expected one node")]
#[error("File was empty, expected one node")]
#[diagnostic(code(gen_completions::deser::empty_file), url(docsrs))]
EmptyFile,

#[error("expected exactly one node, got {0}")]
#[error("Expected exactly one node, got {0}")]
#[diagnostic(code(gen_completions::deser::too_many_nodes), url(docsrs))]
TooManyNodes(usize),

/// The text was valid KDL but could not be read as a [`CommandInfo`]
#[error("errors encountered while reading command information")]
#[diagnostic(code(gen_completions::deser::parse_error), url(docsrs), help("get good"))]
#[error("Errors encountered while reading command information")]
#[diagnostic(
code(gen_completions::deser::parse_error),
url(docsrs),
help("get good")
)]
ParseError {
#[source_code]
text: String,
#[diagnostic_source]
#[source]
source: ParseError,
#[related]
related: Vec<ParseError>,
},
}

#[derive(Debug, Diagnostic, Error)]
pub enum ParseError {
#[error("unexpected child {child_name}")]
#[diagnostic(
code(gen_completions::deser::kdl::unexpected_child),
url(docsrs)
)]
UnexpectedChild {
child_name: String,
allowed: String,
Expand All @@ -43,7 +53,11 @@ pub enum ParseError {
},

#[error("duplicate child node")]
#[diagnostic(help("merge the {child_name} nodes together"))]
#[diagnostic(
code(gen_completions::deser::kdl::duplicate_child),
url(docsrs),
help("merge the {child_name} nodes together")
)]
DuplicateChild {
child_name: String,
#[label("duplicate node named {child_name}")]
Expand All @@ -53,6 +67,7 @@ pub enum ParseError {
},

#[error("duplicate flag")]
#[diagnostic(code(gen_completions::deser::kdl::duplicate_flag), url(docsrs))]
DuplicateFlag {
flag: String,
#[label("duplicate flag")]
Expand All @@ -62,21 +77,31 @@ pub enum ParseError {
},

#[error("flags should be strings, got {msg}")]
#[diagnostic(help("wrap your flags in quotes"))]
#[diagnostic(
code(gen_completions::deser::kdl::invalid_flag),
url(docsrs),
help("wrap your flags in quotes")
)]
InvalidFlag {
msg: String,
#[label("should be a single string")]
span: SourceSpan,
},

#[error("invalid description, expected a single string")]
#[diagnostic(code(gen_completions::deser::kdl::invalid_desc), url(docsrs))]
InvalidDescription(#[label("should be a single string")] SourceSpan),

#[error("type is empty")]
#[diagnostic(help("remove the type node entirely"))]
#[diagnostic(
code(gen_completions::deser::kdl::empty_type),
url(docsrs),
help("remove the type node entirely")
)]
EmptyType(#[label("node has no children")] SourceSpan),

#[error("invalid type")]
#[diagnostic(code(gen_completions::deser::kdl::invalid_type), url(docsrs))]
InvalidType(String, #[label("unknown type {0}")] SourceSpan),
}

Expand All @@ -98,12 +123,9 @@ pub fn parse_from_str(text: &str) -> Result<CommandInfo> {
} else if nodes.len() > 1 {
Err(KdlDeserError::TooManyNodes(nodes.len()))
} else {
kdl_to_cmd_info(&nodes[0]).map_err(|mut errors| {
println!("{:?}", errors);
KdlDeserError::ParseError {
text: text.to_string(),
source: errors.pop().unwrap(),
}
kdl_to_cmd_info(&nodes[0]).map_err(|mut errors| KdlDeserError::ParseError {
text: text.to_string(),
related: vec![errors.pop().unwrap()],
})
}
}
Expand Down
1 change: 1 addition & 0 deletions src/parse_deser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ pub fn parse(file: impl AsRef<Path>) -> Result<CommandInfo> {
};
parse_from_str(&text, format).map_err(|e| Error::Deser {
file_path,
text,
source: e,
})
} else {
Expand Down

0 comments on commit a7665d1

Please sign in to comment.