mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-08-31 15:47:31 +00:00
Make config.rs a single source of truth for configuration.
Configuration is editor-independent. For this reason, we pick JSON-schema as the repr of the source of truth. We do specify it using rust-macros and some quick&dirty hackery though. The idea for syncing truth with package.json is to just do that manually, but there's a test to check that they are actually synced. There's CLI to print config's json schema: $ rust-analyzer --print-config-schema We go with a CLI rather than LSP request/response to make it easier to incorporate the thing into extension's static config. This is roughtly how we put the thing in package.json.
This commit is contained in:
parent
e2e6b709e6
commit
2544abbf86
7 changed files with 674 additions and 447 deletions
|
@ -321,12 +321,11 @@ fn lines_match_works() {
|
|||
/// as paths). You can use a `"{...}"` string literal as a wildcard for
|
||||
/// arbitrary nested JSON. Arrays are sorted before comparison.
|
||||
pub fn find_mismatch<'a>(expected: &'a Value, actual: &'a Value) -> Option<(&'a Value, &'a Value)> {
|
||||
use serde_json::Value::*;
|
||||
match (expected, actual) {
|
||||
(&Number(ref l), &Number(ref r)) if l == r => None,
|
||||
(&Bool(l), &Bool(r)) if l == r => None,
|
||||
(&String(ref l), &String(ref r)) if lines_match(l, r) => None,
|
||||
(&Array(ref l), &Array(ref r)) => {
|
||||
(Value::Number(l), Value::Number(r)) if l == r => None,
|
||||
(Value::Bool(l), Value::Bool(r)) if l == r => None,
|
||||
(Value::String(l), Value::String(r)) if lines_match(l, r) => None,
|
||||
(Value::Array(l), Value::Array(r)) => {
|
||||
if l.len() != r.len() {
|
||||
return Some((expected, actual));
|
||||
}
|
||||
|
@ -350,17 +349,26 @@ pub fn find_mismatch<'a>(expected: &'a Value, actual: &'a Value) -> Option<(&'a
|
|||
None
|
||||
}
|
||||
}
|
||||
(&Object(ref l), &Object(ref r)) => {
|
||||
(Value::Object(l), Value::Object(r)) => {
|
||||
fn sorted_values(obj: &serde_json::Map<String, Value>) -> Vec<&Value> {
|
||||
let mut entries = obj.iter().collect::<Vec<_>>();
|
||||
entries.sort_by_key(|it| it.0);
|
||||
entries.into_iter().map(|(_k, v)| v).collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
let same_keys = l.len() == r.len() && l.keys().all(|k| r.contains_key(k));
|
||||
if !same_keys {
|
||||
return Some((expected, actual));
|
||||
}
|
||||
|
||||
l.values().zip(r.values()).filter_map(|(l, r)| find_mismatch(l, r)).next()
|
||||
let l = sorted_values(l);
|
||||
let r = sorted_values(r);
|
||||
|
||||
l.into_iter().zip(r).filter_map(|(l, r)| find_mismatch(l, r)).next()
|
||||
}
|
||||
(&Null, &Null) => None,
|
||||
(Value::Null, Value::Null) => None,
|
||||
// magic string literal "{...}" acts as wildcard for any sub-JSON
|
||||
(&String(ref l), _) if l == "{...}" => None,
|
||||
(Value::String(l), _) if l == "{...}" => None,
|
||||
_ => Some((expected, actual)),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue