Skip to content

Commit f55f790

Browse files
committed
refactor(frontmatter): Switch to custom error type
1 parent 24bb93c commit f55f790

File tree

2 files changed

+42
-15
lines changed

2 files changed

+42
-15
lines changed

src/cargo/util/frontmatter.rs

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use crate::CargoResult;
2-
31
type Span = std::ops::Range<usize>;
42

53
#[derive(Debug)]
@@ -22,7 +20,7 @@ pub struct ScriptSource<'s> {
2220
}
2321

2422
impl<'s> ScriptSource<'s> {
25-
pub fn parse(raw: &'s str) -> CargoResult<Self> {
23+
pub fn parse(raw: &'s str) -> Result<Self, FrontmatterError> {
2624
use winnow::stream::FindSlice as _;
2725
use winnow::stream::Location as _;
2826
use winnow::stream::Offset as _;
@@ -67,9 +65,9 @@ impl<'s> ScriptSource<'s> {
6765
}
6866
1 | 2 => {
6967
// either not a frontmatter or invalid frontmatter opening
70-
anyhow::bail!(
68+
return Err(FrontmatterError::new(format!(
7169
"found {fence_length} `{FENCE_CHAR}` in rust frontmatter, expected at least 3"
72-
)
70+
)));
7371
}
7472
_ => {}
7573
}
@@ -78,7 +76,9 @@ impl<'s> ScriptSource<'s> {
7876
let open_end = input.current_token_start();
7977
source.open = Some(open_start..open_end);
8078
let Some(info_nl) = input.find_slice("\n") else {
81-
anyhow::bail!("no closing `{fence_pattern}` found for frontmatter");
79+
return Err(FrontmatterError::new(format!(
80+
"no closing `{fence_pattern}` found for frontmatter"
81+
)));
8282
};
8383
let info = input.next_slice(info_nl.start);
8484
let info = info.trim_matches(is_whitespace);
@@ -91,7 +91,9 @@ impl<'s> ScriptSource<'s> {
9191
// Ends with a line that starts with a matching number of `-` only followed by whitespace
9292
let nl_fence_pattern = format!("\n{fence_pattern}");
9393
let Some(frontmatter_nl) = input.find_slice(nl_fence_pattern.as_str()) else {
94-
anyhow::bail!("no closing `{fence_pattern}` found for frontmatter");
94+
return Err(FrontmatterError::new(format!(
95+
"no closing `{fence_pattern}` found for frontmatter"
96+
)));
9597
};
9698
let frontmatter_start = input.current_token_start() + 1; // skip nl from infostring
9799
let _ = input.next_slice(frontmatter_nl.start + 1);
@@ -111,14 +113,18 @@ impl<'s> ScriptSource<'s> {
111113
let after_closing_fence = after_closing_fence.trim_matches(is_whitespace);
112114
if !after_closing_fence.is_empty() {
113115
// extra characters beyond the original fence pattern, even if they are extra `-`
114-
anyhow::bail!("trailing characters found after frontmatter close");
116+
return Err(FrontmatterError::new(format!(
117+
"trailing characters found after frontmatter close"
118+
)));
115119
}
116120

117121
source.content = content_start..content_end;
118122

119123
let repeat = Self::parse(source.content())?;
120124
if repeat.frontmatter.is_some() {
121-
anyhow::bail!("only one frontmatter is supported");
125+
return Err(FrontmatterError::new(format!(
126+
"only one frontmatter is supported"
127+
)));
122128
}
123129

124130
Ok(source)
@@ -232,6 +238,27 @@ fn is_whitespace(c: char) -> bool {
232238
)
233239
}
234240

241+
#[derive(Debug)]
242+
pub struct FrontmatterError {
243+
message: String,
244+
}
245+
246+
impl FrontmatterError {
247+
pub fn new(message: impl Into<String>) -> Self {
248+
Self {
249+
message: message.into(),
250+
}
251+
}
252+
}
253+
254+
impl std::fmt::Display for FrontmatterError {
255+
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
256+
self.message.fmt(fmt)
257+
}
258+
}
259+
260+
impl std::error::Error for FrontmatterError {}
261+
235262
#[cfg(test)]
236263
mod test {
237264
use snapbox::assert_data_eq;

src/cargo/util/toml/embedded.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
use cargo_util_schemas::manifest::PackageName;
22

3-
use crate::CargoResult;
3+
use crate::util::frontmatter::FrontmatterError;
44
use crate::util::frontmatter::ScriptSource;
55
use crate::util::restricted_names;
66

7-
pub(super) fn expand_manifest(content: &str) -> CargoResult<String> {
7+
pub(super) fn expand_manifest(content: &str) -> Result<String, FrontmatterError> {
88
let source = ScriptSource::parse(content)?;
99
if let Some(span) = source.frontmatter_span() {
1010
match source.info() {
1111
Some("cargo") | None => {}
1212
Some(other) => {
1313
if let Some(remainder) = other.strip_prefix("cargo,") {
14-
anyhow::bail!(
14+
return Err(FrontmatterError::new(format!(
1515
"cargo does not support frontmatter infostring attributes like `{remainder}` at this time"
16-
)
16+
)));
1717
} else {
18-
anyhow::bail!(
18+
return Err(FrontmatterError::new(format!(
1919
"frontmatter infostring `{other}` is unsupported by cargo; specify `cargo` for embedding a manifest"
20-
)
20+
)));
2121
}
2222
}
2323
}

0 commit comments

Comments
 (0)