Skip to content

Commit b26b533

Browse files
committed
Auto merge of #12317 - weihanglo:inheritable-macro, r=Muscraft
refactor: use macro to remove duplication of workspace inheritable fields getters
2 parents be42872 + e313b61 commit b26b533

File tree

1 file changed

+71
-159
lines changed

1 file changed

+71
-159
lines changed

src/cargo/util/toml/mod.rs

Lines changed: 71 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -1595,178 +1595,89 @@ pub struct InheritableFields {
15951595
ws_root: PathBuf,
15961596
}
15971597

1598-
impl InheritableFields {
1599-
pub fn update_deps(&mut self, deps: Option<BTreeMap<String, TomlDependency>>) {
1600-
self.dependencies = deps;
1601-
}
1602-
1603-
pub fn update_lints(&mut self, lints: Option<TomlLints>) {
1604-
self.lints = lints;
1605-
}
1606-
1607-
pub fn update_ws_path(&mut self, ws_root: PathBuf) {
1608-
self.ws_root = ws_root;
1609-
}
1610-
1611-
pub fn dependencies(&self) -> CargoResult<BTreeMap<String, TomlDependency>> {
1612-
self.dependencies.clone().map_or(
1613-
Err(anyhow!("`workspace.dependencies` was not defined")),
1614-
|d| Ok(d),
1615-
)
1616-
}
1617-
1618-
pub fn lints(&self) -> CargoResult<TomlLints> {
1619-
self.lints
1620-
.clone()
1621-
.map_or(Err(anyhow!("`workspace.lints` was not defined")), |d| Ok(d))
1622-
}
1598+
/// Defines simple getter methods for inheritable fields.
1599+
macro_rules! inheritable_field_getter {
1600+
( $(($key:literal, $field:ident -> $ret:ty),)* ) => (
1601+
$(
1602+
#[doc = concat!("Gets the field `workspace.", $key, "`.")]
1603+
pub fn $field(&self) -> CargoResult<$ret> {
1604+
let Some(val) = &self.$field else {
1605+
bail!("`workspace.{}` was not defined", $key);
1606+
};
1607+
Ok(val.clone())
1608+
}
1609+
)*
1610+
)
1611+
}
16231612

1613+
impl InheritableFields {
1614+
inheritable_field_getter! {
1615+
// Please keep this list lexicographically ordered.
1616+
("dependencies", dependencies -> BTreeMap<String, TomlDependency>),
1617+
("lints", lints -> TomlLints),
1618+
("package.authors", authors -> Vec<String>),
1619+
("package.badges", badges -> BTreeMap<String, BTreeMap<String, String>>),
1620+
("package.categories", categories -> Vec<String>),
1621+
("package.description", description -> String),
1622+
("package.documentation", documentation -> String),
1623+
("package.edition", edition -> String),
1624+
("package.exclude", exclude -> Vec<String>),
1625+
("package.homepage", homepage -> String),
1626+
("package.include", include -> Vec<String>),
1627+
("package.keywords", keywords -> Vec<String>),
1628+
("package.license", license -> String),
1629+
("package.publish", publish -> VecStringOrBool),
1630+
("package.repository", repository -> String),
1631+
("package.rust-version", rust_version -> String),
1632+
("package.version", version -> semver::Version),
1633+
}
1634+
1635+
/// Gets a workspace dependency with the `name`.
16241636
pub fn get_dependency(&self, name: &str, package_root: &Path) -> CargoResult<TomlDependency> {
1625-
self.dependencies.clone().map_or(
1626-
Err(anyhow!("`workspace.dependencies` was not defined")),
1627-
|deps| {
1628-
deps.get(name).map_or(
1629-
Err(anyhow!(
1630-
"`dependency.{}` was not found in `workspace.dependencies`",
1631-
name
1632-
)),
1633-
|dep| {
1634-
let mut dep = dep.clone();
1635-
if let TomlDependency::Detailed(detailed) = &mut dep {
1636-
detailed.resolve_path(name, self.ws_root(), package_root)?
1637-
}
1638-
Ok(dep)
1639-
},
1640-
)
1641-
},
1642-
)
1643-
}
1644-
1645-
pub fn version(&self) -> CargoResult<semver::Version> {
1646-
self.version.clone().map_or(
1647-
Err(anyhow!("`workspace.package.version` was not defined")),
1648-
|d| Ok(d),
1649-
)
1650-
}
1651-
1652-
pub fn authors(&self) -> CargoResult<Vec<String>> {
1653-
self.authors.clone().map_or(
1654-
Err(anyhow!("`workspace.package.authors` was not defined")),
1655-
|d| Ok(d),
1656-
)
1657-
}
1658-
1659-
pub fn description(&self) -> CargoResult<String> {
1660-
self.description.clone().map_or(
1661-
Err(anyhow!("`workspace.package.description` was not defined")),
1662-
|d| Ok(d),
1663-
)
1664-
}
1665-
1666-
pub fn homepage(&self) -> CargoResult<String> {
1667-
self.homepage.clone().map_or(
1668-
Err(anyhow!("`workspace.package.homepage` was not defined")),
1669-
|d| Ok(d),
1670-
)
1671-
}
1672-
1673-
pub fn documentation(&self) -> CargoResult<String> {
1674-
self.documentation.clone().map_or(
1675-
Err(anyhow!("`workspace.package.documentation` was not defined")),
1676-
|d| Ok(d),
1677-
)
1678-
}
1679-
1680-
pub fn readme(&self, package_root: &Path) -> CargoResult<StringOrBool> {
1681-
readme_for_package(self.ws_root.as_path(), self.readme.clone()).map_or(
1682-
Err(anyhow!("`workspace.package.readme` was not defined")),
1683-
|readme| {
1684-
let rel_path =
1685-
resolve_relative_path("readme", &self.ws_root, package_root, &readme)?;
1686-
Ok(StringOrBool::String(rel_path))
1687-
},
1688-
)
1689-
}
1690-
1691-
pub fn keywords(&self) -> CargoResult<Vec<String>> {
1692-
self.keywords.clone().map_or(
1693-
Err(anyhow!("`workspace.package.keywords` was not defined")),
1694-
|d| Ok(d),
1695-
)
1696-
}
1697-
1698-
pub fn categories(&self) -> CargoResult<Vec<String>> {
1699-
self.categories.clone().map_or(
1700-
Err(anyhow!("`workspace.package.categories` was not defined")),
1701-
|d| Ok(d),
1702-
)
1703-
}
1704-
1705-
pub fn license(&self) -> CargoResult<String> {
1706-
self.license.clone().map_or(
1707-
Err(anyhow!("`workspace.package.license` was not defined")),
1708-
|d| Ok(d),
1709-
)
1637+
let Some(deps) = &self.dependencies else {
1638+
bail!("`workspace.dependencies` was not defined");
1639+
};
1640+
let Some(dep) = deps.get(name) else {
1641+
bail!("`dependency.{name}` was not found in `workspace.dependencies`");
1642+
};
1643+
let mut dep = dep.clone();
1644+
if let TomlDependency::Detailed(detailed) = &mut dep {
1645+
detailed.resolve_path(name, self.ws_root(), package_root)?;
1646+
}
1647+
Ok(dep)
17101648
}
17111649

1650+
/// Gets the field `workspace.package.license-file`.
17121651
pub fn license_file(&self, package_root: &Path) -> CargoResult<String> {
1713-
self.license_file.clone().map_or(
1714-
Err(anyhow!("`workspace.package.license_file` was not defined")),
1715-
|d| resolve_relative_path("license-file", &self.ws_root, package_root, &d),
1716-
)
1717-
}
1718-
1719-
pub fn repository(&self) -> CargoResult<String> {
1720-
self.repository.clone().map_or(
1721-
Err(anyhow!("`workspace.package.repository` was not defined")),
1722-
|d| Ok(d),
1723-
)
1724-
}
1725-
1726-
pub fn publish(&self) -> CargoResult<VecStringOrBool> {
1727-
self.publish.clone().map_or(
1728-
Err(anyhow!("`workspace.package.publish` was not defined")),
1729-
|d| Ok(d),
1730-
)
1731-
}
1732-
1733-
pub fn edition(&self) -> CargoResult<String> {
1734-
self.edition.clone().map_or(
1735-
Err(anyhow!("`workspace.package.edition` was not defined")),
1736-
|d| Ok(d),
1737-
)
1652+
let Some(license_file) = &self.license_file else {
1653+
bail!("`workspace.package.license-file` was not defined");
1654+
};
1655+
resolve_relative_path("license-file", &self.ws_root, package_root, license_file)
17381656
}
17391657

1740-
pub fn rust_version(&self) -> CargoResult<String> {
1741-
self.rust_version.clone().map_or(
1742-
Err(anyhow!("`workspace.package.rust-version` was not defined")),
1743-
|d| Ok(d),
1744-
)
1658+
/// Gets the field `workspace.package.readme`.
1659+
pub fn readme(&self, package_root: &Path) -> CargoResult<StringOrBool> {
1660+
let Some(readme) = readme_for_package(self.ws_root.as_path(), self.readme.as_ref()) else {
1661+
bail!("`workspace.package.readme` was not defined");
1662+
};
1663+
resolve_relative_path("readme", &self.ws_root, package_root, &readme)
1664+
.map(StringOrBool::String)
17451665
}
17461666

1747-
pub fn badges(&self) -> CargoResult<BTreeMap<String, BTreeMap<String, String>>> {
1748-
self.badges.clone().map_or(
1749-
Err(anyhow!("`workspace.package.badges` was not defined")),
1750-
|d| Ok(d),
1751-
)
1667+
pub fn ws_root(&self) -> &PathBuf {
1668+
&self.ws_root
17521669
}
17531670

1754-
pub fn exclude(&self) -> CargoResult<Vec<String>> {
1755-
self.exclude.clone().map_or(
1756-
Err(anyhow!("`workspace.package.exclude` was not defined")),
1757-
|d| Ok(d),
1758-
)
1671+
pub fn update_deps(&mut self, deps: Option<BTreeMap<String, TomlDependency>>) {
1672+
self.dependencies = deps;
17591673
}
17601674

1761-
pub fn include(&self) -> CargoResult<Vec<String>> {
1762-
self.include.clone().map_or(
1763-
Err(anyhow!("`workspace.package.include` was not defined")),
1764-
|d| Ok(d),
1765-
)
1675+
pub fn update_lints(&mut self, lints: Option<TomlLints>) {
1676+
self.lints = lints;
17661677
}
17671678

1768-
pub fn ws_root(&self) -> &PathBuf {
1769-
&self.ws_root
1679+
pub fn update_ws_path(&mut self, ws_root: PathBuf) {
1680+
self.ws_root = ws_root;
17701681
}
17711682
}
17721683

@@ -2464,7 +2375,8 @@ impl TomlManifest {
24642375
.readme
24652376
.clone()
24662377
.map(|mw| mw.resolve("readme", || inherit()?.readme(package_root)))
2467-
.transpose()?,
2378+
.transpose()?
2379+
.as_ref(),
24682380
),
24692381
authors: package
24702382
.authors
@@ -3062,7 +2974,7 @@ fn inheritable_from_path(
30622974
}
30632975

30642976
/// Returns the name of the README file for a [`TomlPackage`].
3065-
pub fn readme_for_package(package_root: &Path, readme: Option<StringOrBool>) -> Option<String> {
2977+
pub fn readme_for_package(package_root: &Path, readme: Option<&StringOrBool>) -> Option<String> {
30662978
match &readme {
30672979
None => default_readme_from_package_root(package_root),
30682980
Some(value) => match value {

0 commit comments

Comments
 (0)