mirror of
https://github.com/rust-lang/cargo
synced 2024-10-13 03:02:45 +00:00
feat(embedded): Add prefix-char frontmatter syntax support
This is a follow up to #13241 with another syntax being discussed. This one is a bit more polarizing but we're hoping first-hand experience with it can help people get a feel for how well it works in practice. As the experiment is meant to be short-lived, this is implemented in a hacky way and docs aren't updated.
This commit is contained in:
parent
f9946d15df
commit
b77ce7fa29
|
@ -185,7 +185,7 @@ fn sanitize_name(name: &str) -> String {
|
|||
struct Source<'s> {
|
||||
shebang: Option<&'s str>,
|
||||
info: Option<&'s str>,
|
||||
frontmatter: Option<&'s str>,
|
||||
frontmatter: Option<String>,
|
||||
content: &'s str,
|
||||
}
|
||||
|
||||
|
@ -234,11 +234,14 @@ fn split_source(input: &str) -> CargoResult<Source<'_>> {
|
|||
0 => {
|
||||
return Ok(source);
|
||||
}
|
||||
1 if tick_char == '#' => {
|
||||
// Attribute
|
||||
return Ok(source);
|
||||
}
|
||||
2 if tick_char == '#' => {
|
||||
return split_prefix_source(source, "##");
|
||||
}
|
||||
1 | 2 => {
|
||||
if tick_char == '#' {
|
||||
// Attribute
|
||||
return Ok(source);
|
||||
}
|
||||
anyhow::bail!("found {tick_end} `{tick_char}` in rust frontmatter, expected at least 3")
|
||||
}
|
||||
_ => source.content.split_at(tick_end),
|
||||
|
@ -252,7 +255,7 @@ fn split_source(input: &str) -> CargoResult<Source<'_>> {
|
|||
let Some((frontmatter, content)) = source.content.split_once(fence_pattern) else {
|
||||
anyhow::bail!("no closing `{fence_pattern}` found for frontmatter");
|
||||
};
|
||||
source.frontmatter = Some(frontmatter);
|
||||
source.frontmatter = Some(frontmatter.to_owned());
|
||||
source.content = content;
|
||||
|
||||
let (line, content) = source
|
||||
|
@ -268,6 +271,22 @@ fn split_source(input: &str) -> CargoResult<Source<'_>> {
|
|||
Ok(source)
|
||||
}
|
||||
|
||||
fn split_prefix_source<'s>(mut source: Source<'s>, prefix: &str) -> CargoResult<Source<'s>> {
|
||||
let mut frontmatter = String::new();
|
||||
while let Some(rest) = source.content.strip_prefix(prefix) {
|
||||
if !rest.is_empty() && !rest.starts_with(' ') {
|
||||
anyhow::bail!("frontmatter must have a space between `##` and the content");
|
||||
}
|
||||
let (line, rest) = rest.split_once('\n').unwrap_or((rest, ""));
|
||||
frontmatter.push_str(" ");
|
||||
frontmatter.push_str(line);
|
||||
frontmatter.push('\n');
|
||||
source.content = rest;
|
||||
}
|
||||
source.frontmatter = Some(frontmatter);
|
||||
Ok(source)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_expand {
|
||||
use super::*;
|
||||
|
@ -375,7 +394,7 @@ fn main() {}
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_dash() {
|
||||
fn test_dash_fence() {
|
||||
snapbox::assert_matches(
|
||||
r#"[[bin]]
|
||||
name = "test-"
|
||||
|
@ -408,7 +427,7 @@ fn main() {}
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_hash() {
|
||||
fn test_hash_fence() {
|
||||
snapbox::assert_matches(
|
||||
r#"[[bin]]
|
||||
name = "test-"
|
||||
|
@ -436,6 +455,37 @@ strip = true
|
|||
time="0.1.25"
|
||||
###
|
||||
fn main() {}
|
||||
"#),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hash_prefix() {
|
||||
snapbox::assert_matches(
|
||||
r#"[[bin]]
|
||||
name = "test-"
|
||||
path = [..]
|
||||
|
||||
[dependencies]
|
||||
time = "0.1.25"
|
||||
|
||||
[package]
|
||||
autobenches = false
|
||||
autobins = false
|
||||
autoexamples = false
|
||||
autotests = false
|
||||
build = false
|
||||
edition = "2021"
|
||||
name = "test-"
|
||||
|
||||
[profile.release]
|
||||
strip = true
|
||||
|
||||
[workspace]
|
||||
"#,
|
||||
si!(r#"## [dependencies]
|
||||
## time="0.1.25"
|
||||
fn main() {}
|
||||
"#),
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue