feat: add search
This commit is contained in:
8
Cargo.lock
generated
8
Cargo.lock
generated
@@ -134,9 +134,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.94"
|
version = "0.2.95"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e"
|
checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "line-wrap"
|
name = "line-wrap"
|
||||||
@@ -210,9 +210,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rust_util"
|
name = "rust_util"
|
||||||
version = "0.6.33"
|
version = "0.6.39"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f06fc6f605c69092884583efb526f0db6d8e81a9fa8f0ec574a5560c02fd8a07"
|
checksum = "21b1ebfe593930e71805e37c914bf2dc48c2194b9dff7f0f1af8c59f92c5cff5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libc",
|
"libc",
|
||||||
|
|||||||
@@ -7,6 +7,6 @@ edition = "2018"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
plist = "1.1.0"
|
plist = "1.1"
|
||||||
clap = "2.33.3"
|
clap = "2.33"
|
||||||
rust_util = "0.6.33"
|
rust_util = "0.6"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ pub struct ParsedArgs {
|
|||||||
pub in_file: String,
|
pub in_file: String,
|
||||||
pub format: PlistFormat,
|
pub format: PlistFormat,
|
||||||
pub out_file: Option<String>,
|
pub out_file: Option<String>,
|
||||||
|
pub search: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_args(matches: ArgMatches<'static>) -> ParsedArgs {
|
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."),
|
_ => failure_and_exit!("Plist format error."),
|
||||||
},
|
},
|
||||||
out_file: matches.value_of("out").map(ToString::to_string),
|
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"])
|
.possible_values(&["xml", "binary", "bin"])
|
||||||
.help("Output plist format")
|
.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("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"))
|
.arg(Arg::with_name("FILE").required(true).index(1).help("Input plist file name"))
|
||||||
.get_matches()
|
.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 utils;
|
||||||
mod args;
|
mod args;
|
||||||
|
mod find;
|
||||||
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use plist::Value;
|
use plist::Value;
|
||||||
@@ -17,6 +18,16 @@ fn main() {
|
|||||||
let plist_value = Value::from_file(&parsed_args.in_file).unwrap_or_else(|e| {
|
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);
|
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
|
// write plist to file or stdout
|
||||||
if let Some(out_file) = parsed_args.out_file {
|
if let Some(out_file) = parsed_args.out_file {
|
||||||
if File::open(&out_file).is_ok() {
|
if File::open(&out_file).is_ok() {
|
||||||
|
|||||||
Reference in New Issue
Block a user