|
1 | | -use std::collections::HashSet; |
2 | | - |
3 | 1 | use rayon::prelude::*; |
4 | 2 |
|
5 | 3 | pub mod format; |
@@ -392,36 +390,49 @@ pub fn create_rows<'a, T: IntoIterator<Item = &'a serde_json::Value>>(iter: T) - |
392 | 390 | rows |
393 | 391 | } |
394 | 392 |
|
395 | | -fn collect_paths(value: &serde_json::Value, current_path: &str, paths: &mut HashSet<String>) { |
396 | | - paths.insert(current_path.to_string()); |
| 393 | +#[derive(Debug)] |
| 394 | +pub struct PathIterator<'a> { |
| 395 | + stack: Vec<(String, &'a serde_json::Value)>, |
| 396 | +} |
397 | 397 |
|
398 | | - match value { |
399 | | - serde_json::Value::Object(obj) => { |
400 | | - for (key, val) in obj { |
401 | | - let new_path = if current_path == "." { |
402 | | - format!(".{}", key) |
403 | | - } else { |
404 | | - format!("{}.{}", current_path, key) |
405 | | - }; |
406 | | - collect_paths(val, &new_path, paths); |
407 | | - } |
408 | | - } |
409 | | - serde_json::Value::Array(arr) => { |
410 | | - for (i, val) in arr.iter().enumerate() { |
411 | | - let new_path = format!("{}[{}]", current_path, i); |
412 | | - collect_paths(val, &new_path, paths); |
| 398 | +impl<'a> Iterator for PathIterator<'a> { |
| 399 | + type Item = String; |
| 400 | + |
| 401 | + fn next(&mut self) -> Option<Self::Item> { |
| 402 | + if let Some((current_path, value)) = self.stack.pop() { |
| 403 | + match value { |
| 404 | + serde_json::Value::Object(obj) => { |
| 405 | + for (key, val) in obj.iter() { |
| 406 | + let new_path = if current_path == "." { |
| 407 | + format!(".{}", key) |
| 408 | + } else { |
| 409 | + format!("{}.{}", current_path, key) |
| 410 | + }; |
| 411 | + self.stack.push((new_path, val)); |
| 412 | + } |
| 413 | + } |
| 414 | + serde_json::Value::Array(arr) => { |
| 415 | + for (i, val) in arr.iter().enumerate() { |
| 416 | + let new_path = format!("{}[{}]", current_path, i); |
| 417 | + self.stack.push((new_path, val)); |
| 418 | + } |
| 419 | + } |
| 420 | + _ => {} |
413 | 421 | } |
| 422 | + |
| 423 | + Some(current_path) |
| 424 | + } else { |
| 425 | + None |
414 | 426 | } |
415 | | - _ => {} |
416 | 427 | } |
417 | 428 | } |
418 | 429 |
|
419 | 430 | pub fn get_all_paths<'a, T: IntoIterator<Item = &'a serde_json::Value>>( |
420 | 431 | iter: T, |
421 | | -) -> HashSet<String> { |
422 | | - let mut paths = HashSet::new(); |
| 432 | +) -> impl Iterator<Item = String> + 'a { |
| 433 | + let mut stack = Vec::new(); |
423 | 434 | for value in iter { |
424 | | - collect_paths(value, ".", &mut paths); |
| 435 | + stack.push((".".to_string(), value)); |
425 | 436 | } |
426 | | - paths |
| 437 | + PathIterator { stack } |
427 | 438 | } |
0 commit comments