use std::io::BufRead;
use arrow_schema::ArrowError;
use serde_json::Value;
#[derive(Debug)]
pub struct ValueIter<R: BufRead> {
reader: R,
max_read_records: Option<usize>,
record_count: usize,
line_buf: String,
}
impl<R: BufRead> ValueIter<R> {
pub fn new(reader: R, max_read_records: Option<usize>) -> Self {
Self {
reader,
max_read_records,
record_count: 0,
line_buf: String::new(),
}
}
pub fn record_count(&self) -> usize {
self.record_count
}
}
impl<R: BufRead> Iterator for ValueIter<R> {
type Item = Result<Value, ArrowError>;
fn next(&mut self) -> Option<Self::Item> {
if let Some(max) = self.max_read_records {
if self.record_count >= max {
return None;
}
}
loop {
self.line_buf.truncate(0);
match self.reader.read_line(&mut self.line_buf) {
Ok(0) => {
return None;
}
Err(e) => {
return Some(Err(ArrowError::JsonError(format!(
"Failed to read JSON record: {e}"
))));
}
_ => {
let trimmed_s = self.line_buf.trim();
if trimmed_s.is_empty() {
continue;
}
self.record_count += 1;
return Some(
serde_json::from_str(trimmed_s)
.map_err(|e| ArrowError::JsonError(format!("Not valid JSON: {e}"))),
);
}
}
}
}
}