1use std::io::BufRead;
2use std::path::Path;
3
4use serde_json::Value;
5
6use crate::error::{Result, XurlError};
7
8pub fn parse_json_line(path: &Path, line_no: usize, line: &str) -> Result<Option<Value>> {
9 let trimmed = line.trim();
10 if trimmed.is_empty() {
11 return Ok(None);
12 }
13
14 let value =
15 serde_json::from_str::<Value>(trimmed).map_err(|source| XurlError::InvalidJsonLine {
16 path: path.to_path_buf(),
17 line: line_no,
18 source,
19 })?;
20 Ok(Some(value))
21}
22
23pub fn parse_jsonl_reader<R, F>(path: &Path, mut reader: R, mut on_value: F) -> Result<()>
24where
25 R: BufRead,
26 F: FnMut(usize, Value) -> Result<()>,
27{
28 let mut line_no = 0usize;
29 let mut line = String::new();
30
31 loop {
32 line.clear();
33 let bytes = reader
34 .read_line(&mut line)
35 .map_err(|source| XurlError::Io {
36 path: path.to_path_buf(),
37 source,
38 })?;
39 if bytes == 0 {
40 break;
41 }
42
43 line_no += 1;
44 if let Some(value) = parse_json_line(path, line_no, &line)? {
45 on_value(line_no, value)?;
46 }
47 }
48
49 Ok(())
50}