Skip to content

Commit a5566ce

Browse files
authored
feat: support array of any types in Cargo config (#16103)
### What does this PR try to resolve? This adds the support of array of any types in Cargo config. The motivation of this is mostly from the proposed `-Zconfig-include` syntax (<#7723 (comment)>) ```toml [[include]] path = "a.toml" optional = true [[include]] path = "b.toml" optional = false ``` which before this Cargo only supported array of string. Some design decisions: * **Insta-stabilization**: This is insta- stabilizing a extension of Cargo config. See <#16103 (comment)> * **No `CARGO_*` env support added** — Only the `--config` CLI and file-based configuration start supporting array of any types. `CARGO_*` config environment still doesn't. The only type you can set through environment variable are still primitive types. For advanced env usage, we left it as follow-up to deal with in `-Zadvanced-env` * **Nothing changed in config merging rule** — Nested complex types in array won't merge with any other items, as it still respects the current array merging rule, which appends items. * `cargo config get` now prints inline array/tables for array of nested array/tables. fixes #16111 ### How to test and review this PR? Starting from the fifth commit, those changes are for handling diagnostic regression, as now `Config::from_toml` accepts any types and the invalid type error is delayed from the "TOML->ConfigValue" deserialization to "ConfigValue->Target" Type deserialization. Not sure if we should split it to a separate PR, but the solution here I admit is a bit nasty.
2 parents ebfa12f + 4541603 commit a5566ce

File tree

9 files changed

+887
-204
lines changed

9 files changed

+887
-204
lines changed

src/cargo/ops/cargo_config.rs

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,21 @@ fn print_toml(gctx: &GlobalContext, opts: &GetOptions<'_>, key: &ConfigKey, cv:
115115
}
116116
format!(" # {}", def)
117117
};
118+
119+
fn cv_to_toml(cv: &CV) -> toml_edit::Value {
120+
match cv {
121+
CV::String(s, _) => toml_edit::Value::from(s.as_str()),
122+
CV::Integer(i, _) => toml_edit::Value::from(*i),
123+
CV::Boolean(b, _) => toml_edit::Value::from(*b),
124+
CV::List(l, _) => toml_edit::Value::from_iter(l.iter().map(cv_to_toml)),
125+
CV::Table(t, _) => toml_edit::Value::from_iter({
126+
let mut t: Vec<_> = t.iter().collect();
127+
t.sort_by_key(|t| t.0);
128+
t.into_iter().map(|(k, v)| (k, cv_to_toml(v)))
129+
}),
130+
}
131+
}
132+
118133
match cv {
119134
CV::Boolean(val, def) => drop_println!(gctx, "{} = {}{}", key, val, origin(def)),
120135
CV::Integer(val, def) => drop_println!(gctx, "{} = {}{}", key, val, origin(def)),
@@ -129,31 +144,13 @@ fn print_toml(gctx: &GlobalContext, opts: &GetOptions<'_>, key: &ConfigKey, cv:
129144
if opts.show_origin {
130145
drop_println!(gctx, "{} = [", key);
131146
for cv in vals {
132-
let (val, def) = match cv {
133-
CV::String(s, def) => (s.as_str(), def),
134-
// This is actually unreachable until we start supporting list of different types.
135-
// It should be validated already during the deserialization.
136-
v => todo!("support {} type ", v.desc()),
137-
};
138-
drop_println!(
139-
gctx,
140-
" {}, # {}",
141-
serde::Serialize::serialize(val, toml_edit::ser::ValueSerializer::new())
142-
.unwrap(),
143-
def
144-
);
147+
let val = cv_to_toml(cv);
148+
let def = cv.definition();
149+
drop_println!(gctx, " {val}, # {def}");
145150
}
146151
drop_println!(gctx, "]");
147152
} else {
148-
let vals: toml_edit::Array = vals
149-
.iter()
150-
.map(|cv| match cv {
151-
CV::String(s, _) => toml_edit::Value::from(s.as_str()),
152-
// This is actually unreachable until we start supporting list of different types.
153-
// It should be validated already during the deserialization.
154-
v => todo!("support {} type ", v.desc()),
155-
})
156-
.collect();
153+
let vals: toml_edit::Array = vals.iter().map(cv_to_toml).collect();
157154
drop_println!(gctx, "{} = {}", key, vals);
158155
}
159156
}

0 commit comments

Comments
 (0)