xtask\tasks\fmt\house_rules/
crate_name_nodash.rs1use anyhow::Context;
5use anyhow::anyhow;
6use std::ffi::OsStr;
7use std::path::Path;
8
9pub fn check_crate_name_nodash(path: &Path) -> anyhow::Result<()> {
10 if path.file_name() != Some(OsStr::new("Cargo.toml")) {
15 return Ok(());
16 }
17
18 let contents = fs_err::read_to_string(path)?;
19 let parsed = contents.parse::<toml_edit::DocumentMut>()?;
20
21 let package_name = match parsed
22 .as_table()
23 .get("package")
24 .and_then(|p| p.get("name"))
25 .and_then(|n| n.as_str())
26 {
27 Some(name) => name,
28 None => return Ok(()), };
30
31 if let Some(metadata) = parsed
32 .get("package")
33 .and_then(|x| x.get("metadata"))
34 .and_then(|x| x.get("xtask"))
35 .and_then(|x| x.get("house-rules"))
36 {
37 let props = metadata.as_table().context("invalid metadata format")?;
38 for (k, v) in props.iter() {
39 if k == "allow-dash-in-name" {
40 let is_bin = v
41 .as_bool()
42 .context("invalid type for allow-dash-in-name (must be bool)")?;
43 if is_bin {
44 return Ok(());
45 }
46 }
47 }
48 }
49
50 let bad_package_name = package_name.contains('-');
51 let bad_package_path = {
52 if let Some(parent_path) = path.parent() {
53 parent_path
54 .file_name()
55 .unwrap_or_default()
56 .to_string_lossy()
57 .contains('-')
58 } else {
59 false
60 }
61 };
62
63 let msg = match (bad_package_name, bad_package_path) {
64 (true, true) => "crate name + folder cannot contain '-' char",
65 (true, false) => "crate name cannot contain '-' char",
66 (false, true) => "crate folder cannot contain '-' char",
67 _ => return Ok(()),
68 };
69
70 Err(anyhow!(
71 "{}: name={} folder={}",
72 msg,
73 package_name,
74 path.parent().unwrap_or_else(|| Path::new("")).display()
75 ))
76}