Skip to content

Instantly share code, notes, and snippets.

@unrealhoang
Created August 8, 2022 12:28
Show Gist options
  • Save unrealhoang/583f31117f2fafe8a05563d0134988bf to your computer and use it in GitHub Desktop.
Save unrealhoang/583f31117f2fafe8a05563d0134988bf to your computer and use it in GitHub Desktop.
use std::{io::BufReader, fs::File, borrow::Cow};
use serde::de::{DeserializeSeed, Visitor};
struct GrepDeserialize<'a, 'b> {
needle: &'a str,
cur_path: &'b mut String,
}
struct GrepVisitor<'a, 'b> {
needle: &'a str,
cur_path: &'b mut String,
}
impl<'a, 'b, 'de> Visitor<'de> for GrepVisitor<'a, 'b> {
type Value = ();
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
todo!()
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error, {
if self.cur_path.contains(self.needle) || v.contains(self.needle) {
println!("found: {} = {}", self.cur_path, v);
}
Ok(())
}
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
where
E: serde::de::Error, {
println!("path: {} = {}", self.cur_path, v);
Ok(())
}
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
where
E: serde::de::Error, {
println!("path: {} = {}", self.cur_path, v);
Ok(())
}
fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
where
E: serde::de::Error, {
println!("path: {} = {}", self.cur_path, v);
Ok(())
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: serde::de::MapAccess<'de>,
{
while let Some(key) = map.next_key::<Cow<'de, str>>()? {
self.cur_path.push_str(".");
self.cur_path.push_str(&key);
map.next_value_seed(GrepDeserialize {
needle: self.needle,
cur_path: self.cur_path,
})?;
let drain_from = self.cur_path.len() - key.len() - 1;
self.cur_path.drain(drain_from..);
}
Ok(())
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: serde::de::SeqAccess<'de>,
{
let mut idx_key = 0;
let mut idx_key_str = idx_key.to_string();
self.cur_path.push_str(".");
self.cur_path.push_str(&idx_key_str);
while let Some(_) = seq.next_element_seed(GrepDeserialize {
needle: self.needle,
cur_path: self.cur_path,
})? {
let drain_from = self.cur_path.len() - idx_key_str.len() - 1;
self.cur_path.drain(drain_from..);
idx_key += 1;
idx_key_str = idx_key.to_string();
self.cur_path.push_str(".");
self.cur_path.push_str(&idx_key_str);
}
let drain_from = self.cur_path.len() - idx_key_str.len() - 1;
self.cur_path.drain(drain_from..);
Ok(())
}
}
impl<'a, 'b, 'de> DeserializeSeed<'de> for GrepDeserialize<'a, 'b> {
type Value = ();
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
let v = GrepVisitor {
needle: self.needle,
cur_path: self.cur_path,
};
deserializer.deserialize_any(v)
}
}
fn main() {
let args: Vec<String> = std::env::args().collect();
let file_name = &args[1];
let keyword = &args[2..].join(" ");
println!("Searching {} for '{}':\n", file_name, keyword);
let json_reader = BufReader::new(File::open(file_name).unwrap());
let mut s = String::new();
let grep_deserialize = GrepDeserialize {
needle: keyword,
cur_path: &mut s,
};
let mut deserializer = serde_json::Deserializer::from_reader(json_reader);
_ = grep_deserialize.deserialize(&mut deserializer).unwrap();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment