config: preserve key formatting on set_value()
Some checks are pending
binaries / Build binary artifacts (push) Waiting to run
nix / flake check (push) Waiting to run
build / build (, macos-13) (push) Waiting to run
build / build (, macos-14) (push) Waiting to run
build / build (, ubuntu-latest) (push) Waiting to run
build / build (, windows-latest) (push) Waiting to run
build / build (--all-features, ubuntu-latest) (push) Waiting to run
build / Build jj-lib without Git support (push) Waiting to run
build / Check protos (push) Waiting to run
build / Check formatting (push) Waiting to run
build / Check that MkDocs can build the docs (push) Waiting to run
build / Check that MkDocs can build the docs with latest Python and uv (push) Waiting to run
build / cargo-deny (advisories) (push) Waiting to run
build / cargo-deny (bans licenses sources) (push) Waiting to run
build / Clippy check (push) Waiting to run
Codespell / Codespell (push) Waiting to run
website / prerelease-docs-build-deploy (ubuntu-latest) (push) Waiting to run
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run

I just noticed toml_edit::Table has a format-preserving insert() API. I think
it's better to retain the user-specified quoting style.
This commit is contained in:
Yuya Nishihara 2024-12-28 11:18:40 +09:00
parent 10783f9e70
commit 43ac4faac4
2 changed files with 33 additions and 5 deletions

View file

@ -522,13 +522,13 @@ fn test_config_set_for_user() {
// Ensure test-key successfully written to user config.
let user_config_toml = std::fs::read_to_string(&user_config_path)
.unwrap_or_else(|_| panic!("Failed to read file {}", user_config_path.display()));
insta::assert_snapshot!(user_config_toml, @r###"
insta::assert_snapshot!(user_config_toml, @r#"
test-key = "test-val"
[test-table]
foo = true
"bar()" = 0
"###);
'bar()' = 0
"#);
}
#[test]

View file

@ -397,7 +397,7 @@ impl ConfigLayer {
.map_err(|keys| ConfigUpdateError::WouldOverwriteValue {
name: keys.join("."),
})?;
match parent_table.entry(leaf_key) {
match parent_table.entry_format(leaf_key) {
toml_edit::Entry::Occupied(mut entry) => {
if !entry.get().is_value() {
return Err(ConfigUpdateError::WouldOverwriteTable {
@ -409,6 +409,9 @@ impl ConfigLayer {
}
toml_edit::Entry::Vacant(entry) => {
entry.insert(toml_edit::value(new_value));
// Reset whitespace formatting (i.e. insert space before '=')
let mut new_key = parent_table.key_mut(leaf_key).unwrap();
new_key.leaf_decor_mut().clear();
Ok(None)
}
}
@ -476,7 +479,7 @@ fn ensure_parent_table<'a, 'b>(
let mut keys = name.components();
let leaf_key = keys.next_back().ok_or(&name.0[..])?;
let parent_table = keys.enumerate().try_fold(root_table, |table, (i, key)| {
let sub_item = table.entry(key).or_insert_with(new_implicit_table);
let sub_item = table.entry_format(key).or_insert_with(new_implicit_table);
sub_item.as_table_mut().ok_or(&name.0[..=i])
})?;
Ok((parent_table, leaf_key))
@ -918,6 +921,31 @@ mod tests {
"#);
}
#[test]
fn test_config_layer_set_value_formatting() {
let mut layer = ConfigLayer::empty(ConfigSource::User);
// Quoting style should be preserved on insertion
layer
.set_value(
"'foo' . bar . 'baz'",
ConfigValue::from_str("'value'").unwrap(),
)
.unwrap();
insta::assert_snapshot!(layer.data, @r"
['foo' . bar]
'baz' = 'value'
");
// Style of existing keys isn't updated
layer.set_value("foo.bar.baz", "new value").unwrap();
layer.set_value("foo.'bar'.blah", 0).unwrap();
insta::assert_snapshot!(layer.data, @r#"
['foo' . bar]
'baz' = "new value"
blah = 0
"#);
}
#[test]
fn test_config_layer_delete_value() {
let mut layer = ConfigLayer::empty(ConfigSource::User);