settings: accept trailing commas (#2606)

Z-2357

I've found a crate that handles both comments and trailing commas in
JSON. It is a fork of `serde_json`, but it is maintained & up-to-date.
Sadly RawValue seems to not play nicely with it; I've ran into
deserialisation issues around use of RawValue. For this PR I've migrated
to `Value` API.

Obviously this is just a point of discussion, not something I'd merge
straight away. There may be better solutions to this particular problem.

I've also noticed that `serde_json_lenient` does not handle trailing
commas after bindings array. I'm not sure how big of an issue that is.

Release Notes:
- Improved handling of trailing commas in settings files.
[#1322](https://github.com/zed-industries/community/issues/1322)
This commit is contained in:
Piotr Osiewicz 2023-06-19 18:29:03 +02:00 committed by GitHub
parent 70ccbbafc1
commit 2a3c660d1f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 81 additions and 40 deletions

View file

@ -445,7 +445,7 @@ type WindowBoundsCallback = Box<dyn FnMut(WindowBounds, Uuid, &mut WindowContext
type KeystrokeCallback =
Box<dyn FnMut(&Keystroke, &MatchResult, Option<&Box<dyn Action>>, &mut WindowContext) -> bool>;
type ActiveLabeledTasksCallback = Box<dyn FnMut(&mut AppContext) -> bool>;
type DeserializeActionCallback = fn(json: &str) -> anyhow::Result<Box<dyn Action>>;
type DeserializeActionCallback = fn(json: serde_json::Value) -> anyhow::Result<Box<dyn Action>>;
type WindowShouldCloseSubscriptionCallback = Box<dyn FnMut(&mut AppContext) -> bool>;
pub struct AppContext {
@ -624,14 +624,14 @@ impl AppContext {
pub fn deserialize_action(
&self,
name: &str,
argument: Option<&str>,
argument: Option<serde_json::Value>,
) -> Result<Box<dyn Action>> {
let callback = self
.action_deserializers
.get(name)
.ok_or_else(|| anyhow!("unknown action {}", name))?
.1;
callback(argument.unwrap_or("{}"))
callback(argument.unwrap_or_else(|| serde_json::Value::Object(Default::default())))
.with_context(|| format!("invalid data for action {}", name))
}
@ -5573,7 +5573,7 @@ mod tests {
let action1 = cx
.deserialize_action(
"test::something::ComplexAction",
Some(r#"{"arg": "a", "count": 5}"#),
Some(serde_json::from_str(r#"{"arg": "a", "count": 5}"#).unwrap()),
)
.unwrap();
let action2 = cx