diff options
| author | bors <bors@rust-lang.org> | 2021-02-23 17:24:33 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-02-23 17:24:33 +0000 |
| commit | fe1bf8e05c39bdcc73fc09e246b7209444e389bc (patch) | |
| tree | 9265dd81347434a5b0b6785222fa0b5901e43a1e /src/tools | |
| parent | 019610754363d1d92a8d0f364d2c0909d6f53dfd (diff) | |
| parent | 51511c75b558beddab7fb4b6d8277a872714b87a (diff) | |
| download | rust-fe1bf8e05c39bdcc73fc09e246b7209444e389bc.tar.gz rust-fe1bf8e05c39bdcc73fc09e246b7209444e389bc.zip | |
Auto merge of #82443 - Dylan-DPC:rollup-yni7uio, r=Dylan-DPC
Rollup of 10 pull requests Successful merges: - #81629 (Point out implicit deref coercions in borrow) - #82113 (Improve non_fmt_panic lint.) - #82258 (Implement -Z hir-stats for nested foreign items) - #82296 (Support `pub` on `macro_rules`) - #82297 (Consider auto derefs before warning about write only fields) - #82305 (Remove many RefCells from DocContext) - #82308 (Lower condition of `if` expression before it's "then" block) - #82311 (Jsondocck improvements) - #82362 (Fix mir-cfg dumps) - #82391 (disable atomic_max/min tests in Miri) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'src/tools')
| -rw-r--r-- | src/tools/jsondocck/src/cache.rs | 2 | ||||
| -rw-r--r-- | src/tools/jsondocck/src/main.rs | 71 |
2 files changed, 56 insertions, 17 deletions
diff --git a/src/tools/jsondocck/src/cache.rs b/src/tools/jsondocck/src/cache.rs index b742f0eb3ee..8a6a911321c 100644 --- a/src/tools/jsondocck/src/cache.rs +++ b/src/tools/jsondocck/src/cache.rs @@ -9,6 +9,7 @@ pub struct Cache { root: PathBuf, files: HashMap<PathBuf, String>, values: HashMap<PathBuf, Value>, + pub variables: HashMap<String, Value>, last_path: Option<PathBuf>, } @@ -19,6 +20,7 @@ impl Cache { root: Path::new(doc_dir).to_owned(), files: HashMap::new(), values: HashMap::new(), + variables: HashMap::new(), last_path: None, } } diff --git a/src/tools/jsondocck/src/main.rs b/src/tools/jsondocck/src/main.rs index 6ec292aba64..5020a4917a0 100644 --- a/src/tools/jsondocck/src/main.rs +++ b/src/tools/jsondocck/src/main.rs @@ -2,6 +2,7 @@ use jsonpath_lib::select; use lazy_static::lazy_static; use regex::{Regex, RegexBuilder}; use serde_json::Value; +use std::borrow::Cow; use std::{env, fmt, fs}; mod cache; @@ -48,13 +49,16 @@ pub struct Command { pub enum CommandKind { Has, Count, + Is, + Set, } impl CommandKind { fn validate(&self, args: &[String], command_num: usize, lineno: usize) -> bool { let count = match self { CommandKind::Has => (1..=3).contains(&args.len()), - CommandKind::Count => 3 == args.len(), + CommandKind::Count | CommandKind::Is => 3 == args.len(), + CommandKind::Set => 4 == args.len(), }; if !count { @@ -83,6 +87,8 @@ impl fmt::Display for CommandKind { let text = match self { CommandKind::Has => "has", CommandKind::Count => "count", + CommandKind::Is => "is", + CommandKind::Set => "set", }; write!(f, "{}", text) } @@ -127,6 +133,8 @@ fn get_commands(template: &str) -> Result<Vec<Command>, ()> { let cmd = match cmd { "has" => CommandKind::Has, "count" => CommandKind::Count, + "is" => CommandKind::Is, + "set" => CommandKind::Set, _ => { print_err(&format!("Unrecognized command name `@{}`", cmd), lineno); errors = true; @@ -180,6 +188,7 @@ fn get_commands(template: &str) -> Result<Vec<Command>, ()> { /// Performs the actual work of ensuring a command passes. Generally assumes the command /// is syntactically valid. fn check_command(command: Command, cache: &mut Cache) -> Result<(), CkError> { + // FIXME: Be more granular about why, (e.g. syntax error, count not equal) let result = match command.kind { CommandKind::Has => { match command.args.len() { @@ -188,23 +197,15 @@ fn check_command(command: Command, cache: &mut Cache) -> Result<(), CkError> { // @has <path> <jsonpath> = check path exists 2 => { let val = cache.get_value(&command.args[0])?; - - match select(&val, &command.args[1]) { - Ok(results) => !results.is_empty(), - Err(_) => false, - } + let results = select(&val, &command.args[1]).unwrap(); + !results.is_empty() } // @has <path> <jsonpath> <value> = check *any* item matched by path equals value 3 => { let val = cache.get_value(&command.args[0])?; - match select(&val, &command.args[1]) { - Ok(results) => { - let pat: Value = serde_json::from_str(&command.args[2]).unwrap(); - - !results.is_empty() && results.into_iter().any(|val| *val == pat) - } - Err(_) => false, - } + let results = select(&val, &command.args[1]).unwrap(); + let pat = string_to_value(&command.args[2], cache); + results.contains(&pat.as_ref()) } _ => unreachable!(), } @@ -215,9 +216,37 @@ fn check_command(command: Command, cache: &mut Cache) -> Result<(), CkError> { let expected: usize = command.args[2].parse().unwrap(); let val = cache.get_value(&command.args[0])?; - match select(&val, &command.args[1]) { - Ok(results) => results.len() == expected, - Err(_) => false, + let results = select(&val, &command.args[1]).unwrap(); + results.len() == expected + } + CommandKind::Is => { + // @has <path> <jsonpath> <value> = check *exactly one* item matched by path, and it equals value + assert_eq!(command.args.len(), 3); + let val = cache.get_value(&command.args[0])?; + let results = select(&val, &command.args[1]).unwrap(); + let pat = string_to_value(&command.args[2], cache); + results.len() == 1 && results[0] == pat.as_ref() + } + CommandKind::Set => { + // @set <name> = <path> <jsonpath> + assert_eq!(command.args.len(), 4); + assert_eq!(command.args[1], "=", "Expected an `=`"); + let val = cache.get_value(&command.args[2])?; + let results = select(&val, &command.args[3]).unwrap(); + assert_eq!(results.len(), 1); + match results.len() { + 0 => false, + 1 => { + let r = cache.variables.insert(command.args[0].clone(), results[0].clone()); + assert!(r.is_none(), "Name collision: {} is duplicated", command.args[0]); + true + } + _ => { + panic!( + "Got multiple results in `@set` for `{}`: {:?}", + &command.args[3], results + ); + } } } }; @@ -247,3 +276,11 @@ fn check_command(command: Command, cache: &mut Cache) -> Result<(), CkError> { Ok(()) } } + +fn string_to_value<'a>(s: &str, cache: &'a Cache) -> Cow<'a, Value> { + if s.starts_with("$") { + Cow::Borrowed(&cache.variables[&s[1..]]) + } else { + Cow::Owned(serde_json::from_str(s).unwrap()) + } +} |
