Skip to content

Commit

Permalink
feat(trim-paths): parsing in mainfest and config
Browse files Browse the repository at this point in the history
  • Loading branch information
weihanglo committed Oct 30, 2023
1 parent 28b169b commit 4d29af1
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/cargo/core/profiles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use crate::core::dependency::Artifact;
use crate::core::resolver::features::FeaturesFor;
use crate::core::{PackageId, PackageIdSpec, Resolve, Shell, Target, Workspace};
use crate::util::interning::InternedString;
use crate::util::toml::TomlTrimPaths;
use crate::util::toml::{
ProfilePackageSpec, StringOrBool, TomlDebugInfo, TomlProfile, TomlProfiles,
};
Expand Down Expand Up @@ -556,6 +557,9 @@ fn merge_profile(profile: &mut Profile, toml: &TomlProfile) {
if let Some(flags) = &toml.rustflags {
profile.rustflags = flags.iter().map(InternedString::from).collect();
}
if let Some(trim_paths) = &toml.trim_paths {
profile.trim_paths = Some(trim_paths.clone());
}
profile.strip = match toml.strip {
Some(StringOrBool::Bool(true)) => Strip::Named(InternedString::new("symbols")),
None | Some(StringOrBool::Bool(false)) => Strip::None,
Expand Down Expand Up @@ -599,6 +603,9 @@ pub struct Profile {
#[serde(skip_serializing_if = "Vec::is_empty")] // remove when `rustflags` is stablized
// Note that `rustflags` is used for the cargo-feature `profile_rustflags`
pub rustflags: Vec<InternedString>,
// remove when `-Ztrim-paths` is stablized
#[serde(skip_serializing_if = "Option::is_none")]
pub trim_paths: Option<TomlTrimPaths>,
}

impl Default for Profile {
Expand All @@ -619,6 +626,7 @@ impl Default for Profile {
panic: PanicStrategy::Unwind,
strip: Strip::None,
rustflags: vec![],
trim_paths: None,
}
}
}
Expand Down Expand Up @@ -647,6 +655,7 @@ compact_debug! {
panic
strip
rustflags
trim_paths
)]
}
}
Expand Down Expand Up @@ -713,6 +722,7 @@ impl Profile {
self.rpath,
(self.incremental, self.panic, self.strip),
&self.rustflags,
&self.trim_paths,
)
}
}
Expand Down
127 changes: 127 additions & 0 deletions src/cargo/util/toml/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2692,6 +2692,8 @@ pub struct TomlProfile {
// requires all non-tables to be listed first.
pub package: Option<BTreeMap<ProfilePackageSpec, TomlProfile>>,
pub build_override: Option<Box<TomlProfile>>,
/// Unstable feature `-Ztrim-paths`.
pub trim_paths: Option<TomlTrimPaths>,
}

impl TomlProfile {
Expand Down Expand Up @@ -2892,6 +2894,15 @@ impl TomlProfile {
_ => {}
}
}
if self.trim_paths.is_some() {
match (
features.require(Feature::trim_paths()),
cli_unstable.trim_paths,
) {
(Err(e), false) => return Err(e),
_ => {}
}
}
Ok(())
}

Expand Down Expand Up @@ -3167,6 +3178,122 @@ impl<'de> de::Deserialize<'de> for TomlDebugInfo {
}
}

#[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Serialize)]
#[serde(untagged, rename_all = "kebab-case")]
pub enum TomlTrimPaths {
Values(Vec<TomlTrimPathsValue>),
All,
}

impl TomlTrimPaths {
pub fn none() -> Self {
TomlTrimPaths::Values(Vec::new())
}

pub fn is_none(&self) -> bool {
match self {
TomlTrimPaths::Values(v) => v.is_empty(),
TomlTrimPaths::All => false,
}
}
}

impl<'de> de::Deserialize<'de> for TomlTrimPaths {
fn deserialize<D>(d: D) -> Result<TomlTrimPaths, D::Error>
where
D: de::Deserializer<'de>,
{
use serde::de::Error as _;
let expecting = r#"a boolean, "none", "diagnostics", "macro", "object", "all", or an array with these options"#;
UntaggedEnumVisitor::new()
.expecting(expecting)
.bool(|value| {
Ok(if value {
TomlTrimPaths::All
} else {
TomlTrimPaths::none()
})
})
.string(|v| match v {
"none" => Ok(TomlTrimPaths::none()),
"all" => Ok(TomlTrimPaths::All),
v => {
let d = v.into_deserializer();
let err = |_: D::Error| {
serde_untagged::de::Error::custom(format!("expected {expecting}"))
};
TomlTrimPathsValue::deserialize(d)
.map_err(err)
.map(|v| v.into())
}
})
.seq(|seq| {
let seq: Vec<String> = seq.deserialize()?;
let seq: Vec<_> = seq
.into_iter()
.map(|s| TomlTrimPathsValue::deserialize(s.into_deserializer()))
.collect::<Result<_, _>>()?;
Ok(seq.into())
})
.deserialize(d)
}
}

impl fmt::Display for TomlTrimPaths {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TomlTrimPaths::All => write!(f, "all"),
TomlTrimPaths::Values(v) if v.is_empty() => write!(f, "none"),
TomlTrimPaths::Values(v) => {
let mut iter = v.iter();
if let Some(value) = iter.next() {
write!(f, "{value}")?;
}
for value in iter {
write!(f, ",{value}")?;
}
Ok(())
}
}
}
}

impl From<TomlTrimPathsValue> for TomlTrimPaths {
fn from(value: TomlTrimPathsValue) -> Self {
TomlTrimPaths::Values(vec![value])
}
}

impl From<Vec<TomlTrimPathsValue>> for TomlTrimPaths {
fn from(value: Vec<TomlTrimPathsValue>) -> Self {
TomlTrimPaths::Values(value)
}
}

#[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum TomlTrimPathsValue {
Diagnostics,
Macro,
Object,
}

impl TomlTrimPathsValue {
pub fn as_str(&self) -> &'static str {
match self {
TomlTrimPathsValue::Diagnostics => "diagnostics",
TomlTrimPathsValue::Macro => "macro",
TomlTrimPathsValue::Object => "object",
}
}
}

impl fmt::Display for TomlTrimPathsValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.as_str())
}
}

type TomlLibTarget = TomlTarget;
type TomlBinTarget = TomlTarget;
type TomlExampleTarget = TomlTarget;
Expand Down
1 change: 1 addition & 0 deletions tests/testsuite/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1540,6 +1540,7 @@ fn all_profile_options() {
package: None,
build_override: None,
rustflags: None,
trim_paths: None,
};
let mut overrides = BTreeMap::new();
let key = cargo_toml::ProfilePackageSpec::Spec(PackageIdSpec::parse("foo").unwrap());
Expand Down

0 comments on commit 4d29af1

Please sign in to comment.