feat: add search
This commit is contained in:
8
Cargo.lock
generated
8
Cargo.lock
generated
@@ -134,9 +134,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.94"
|
||||
version = "0.2.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e"
|
||||
checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36"
|
||||
|
||||
[[package]]
|
||||
name = "line-wrap"
|
||||
@@ -210,9 +210,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rust_util"
|
||||
version = "0.6.33"
|
||||
version = "0.6.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f06fc6f605c69092884583efb526f0db6d8e81a9fa8f0ec574a5560c02fd8a07"
|
||||
checksum = "21b1ebfe593930e71805e37c914bf2dc48c2194b9dff7f0f1af8c59f92c5cff5"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"libc",
|
||||
|
||||
@@ -7,6 +7,6 @@ edition = "2018"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
plist = "1.1.0"
|
||||
clap = "2.33.3"
|
||||
rust_util = "0.6.33"
|
||||
plist = "1.1"
|
||||
clap = "2.33"
|
||||
rust_util = "0.6"
|
||||
|
||||
@@ -9,6 +9,7 @@ pub struct ParsedArgs {
|
||||
pub in_file: String,
|
||||
pub format: PlistFormat,
|
||||
pub out_file: Option<String>,
|
||||
pub search: Option<String>,
|
||||
}
|
||||
|
||||
pub fn parse_args(matches: ArgMatches<'static>) -> ParsedArgs {
|
||||
@@ -20,6 +21,7 @@ pub fn parse_args(matches: ArgMatches<'static>) -> ParsedArgs {
|
||||
_ => failure_and_exit!("Plist format error."),
|
||||
},
|
||||
out_file: matches.value_of("out").map(ToString::to_string),
|
||||
search: matches.value_of("search").map(ToString::to_string),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +35,7 @@ pub fn get_args_matches() -> ArgMatches<'static> {
|
||||
.possible_values(&["xml", "binary", "bin"])
|
||||
.help("Output plist format")
|
||||
)
|
||||
.arg(Arg::with_name("search").long("search").takes_value(true).help("Search plist value"))
|
||||
.arg(Arg::with_name("out").short("o").long("out").takes_value(true).help("Output plist file"))
|
||||
.arg(Arg::with_name("FILE").required(true).index(1).help("Input plist file name"))
|
||||
.get_matches()
|
||||
|
||||
55
src/find.rs
Normal file
55
src/find.rs
Normal file
@@ -0,0 +1,55 @@
|
||||
use plist::Value;
|
||||
use rust_util::util_msg::MessageType;
|
||||
|
||||
pub fn find(value: &Value, find_val: &str) -> Vec<(String, String)> {
|
||||
let mut path = vec![];
|
||||
find_value(value, &mut path, find_val)
|
||||
}
|
||||
|
||||
fn find_value(value: &Value, path: &mut Vec<String>, find_val: &str) -> Vec<(String, String)> {
|
||||
rust_util::util_msg::when(MessageType::DEBUG, || {
|
||||
debugging!("Matching key: {}, value: {:?}", make_path(path), value.clone().into_string());
|
||||
});
|
||||
let mut ret = vec![];
|
||||
match value {
|
||||
Value::String(str) => if str.contains(find_val) {
|
||||
ret.push((make_path(path), str.to_string()));
|
||||
}
|
||||
Value::Array(arr) => {
|
||||
for (i, val) in arr.iter().enumerate() {
|
||||
path.push(i.to_string());
|
||||
ret.extend_from_slice(&find_value(val, path, find_val));
|
||||
path.pop();
|
||||
}
|
||||
}
|
||||
Value::Boolean(b) => if b.to_string().eq_ignore_ascii_case(find_val) {
|
||||
ret.push((make_path(path), b.to_string()));
|
||||
}
|
||||
Value::Data(_data) => {
|
||||
warning!("Ignored key: {}", make_path(path));
|
||||
}
|
||||
Value::Date(_date) => { /* IGNORE */ }
|
||||
Value::Dictionary(dict) => {
|
||||
for (k, v) in dict {
|
||||
path.push(k.to_string());
|
||||
ret.extend_from_slice(&find_value(v, path, find_val));
|
||||
path.pop();
|
||||
}
|
||||
}
|
||||
Value::Integer(int) => if int.to_string().contains(find_val) {
|
||||
ret.push((make_path(path), int.to_string()));
|
||||
}
|
||||
Value::Real(f) => if f.to_string().contains(find_val) {
|
||||
ret.push((make_path(path), f.to_string()));
|
||||
}
|
||||
Value::Uid(uid) => if uid.get().to_string().contains(find_val) {
|
||||
ret.push((make_path(path), uid.get().to_string()));
|
||||
}
|
||||
Value::__Nonexhaustive => { /* IGNORE */ }
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
fn make_path(path: &[String]) -> String {
|
||||
":".to_owned() + &path.join(":")
|
||||
}
|
||||
11
src/main.rs
11
src/main.rs
@@ -3,6 +3,7 @@ extern crate rust_util;
|
||||
|
||||
mod utils;
|
||||
mod args;
|
||||
mod find;
|
||||
|
||||
use std::fs::File;
|
||||
use plist::Value;
|
||||
@@ -17,6 +18,16 @@ fn main() {
|
||||
let plist_value = Value::from_file(&parsed_args.in_file).unwrap_or_else(|e| {
|
||||
failure_and_exit!("Read plist file: {}, failed: {}", parsed_args.in_file, e);
|
||||
});
|
||||
|
||||
if let Some(search) = parsed_args.search {
|
||||
let matched = find::find(&plist_value, &search);
|
||||
for (k, v) in &matched {
|
||||
information!("Matched: {} -> {}", k, v);
|
||||
}
|
||||
success!("Found {} values(s)", matched.len());
|
||||
return;
|
||||
}
|
||||
|
||||
// write plist to file or stdout
|
||||
if let Some(out_file) = parsed_args.out_file {
|
||||
if File::open(&out_file).is_ok() {
|
||||
|
||||
Reference in New Issue
Block a user