cargo/util/toml/
embedded.rs1use cargo_util_schemas::manifest::PackageName;
2
3use crate::util::frontmatter::FrontmatterError;
4use crate::util::frontmatter::ScriptSource;
5use crate::util::restricted_names;
6
7pub(super) fn expand_manifest(content: &str) -> Result<String, FrontmatterError> {
8 let source = ScriptSource::parse(content)?;
9 if let Some(span) = source.frontmatter_span() {
10 match source.info() {
11 Some("cargo") | None => {}
12 Some(other) => {
13 let info_span = source.info_span().unwrap();
14 let close_span = source.close_span().unwrap();
15 if let Some(remainder) = other.strip_prefix("cargo,") {
16 return Err(FrontmatterError::new(
17 format!("unsupported frontmatter infostring attributes: `{remainder}`"),
18 info_span,
19 )
20 .push_visible_span(close_span));
21 } else {
22 return Err(FrontmatterError::new(
23 format!(
24 "unsupported frontmatter infostring `{other}`; specify `cargo` for embedding a manifest"
25 ),
26 info_span,
27 ).push_visible_span(close_span));
28 }
29 }
30 }
31
32 let mut frontmatter = content[0..span.end].to_owned();
38 let open_span = source.open_span().unwrap();
39 frontmatter.insert(open_span.start, '#');
40 Ok(frontmatter)
41 } else {
42 let span = source.shebang_span().unwrap_or(0..0);
46 Ok(content[span].to_owned())
47 }
48}
49
50pub fn sanitize_name(name: &str) -> String {
52 let placeholder = if name.contains('_') {
53 '_'
54 } else {
55 '-'
58 };
59
60 let mut name = PackageName::sanitize(name, placeholder).into_inner();
61
62 loop {
63 if restricted_names::is_keyword(&name) {
64 name.push(placeholder);
65 } else if restricted_names::is_conflicting_artifact_name(&name) {
66 name.push(placeholder);
68 } else if name == "test" {
69 name.push(placeholder);
70 } else if restricted_names::is_windows_reserved(&name) {
71 name.push(placeholder);
73 } else {
74 break;
75 }
76 }
77
78 name
79}
80
81#[cfg(test)]
82mod test {
83 use snapbox::assert_data_eq;
84 use snapbox::str;
85
86 use super::*;
87
88 #[track_caller]
89 fn expand(source: &str) -> String {
90 expand_manifest(source).unwrap_or_else(|err| panic!("{}", err))
91 }
92
93 #[test]
94 fn expand_default() {
95 assert_data_eq!(expand(r#"fn main() {}"#), str![""]);
96 }
97
98 #[test]
99 fn expand_dependencies() {
100 assert_data_eq!(
101 expand(
102 r#"---cargo
103[dependencies]
104time="0.1.25"
105---
106fn main() {}
107"#
108 ),
109 str![[r##"
110#---cargo
111[dependencies]
112time="0.1.25"
113
114"##]]
115 );
116 }
117}