use serde::Serialize;
use serde_json::Value as Json;
use crate::{DataError, RecordSource, RowSource, Rows};
pub use crate::record::DEFAULT_SAMPLE;
pub fn read<T: Serialize>(items: impl IntoIterator<Item = T>) -> Result<Rows, DataError> {
RecordSource::new(Records::new(items.into_iter()), usize::MAX)?.collect_rows()
}
pub fn source<T, I>(items: I) -> Result<SerializeSource<I::IntoIter>, DataError>
where
T: Serialize,
I: IntoIterator<Item = T>,
{
source_with_sample(items, DEFAULT_SAMPLE)
}
pub fn source_with_sample<T, I>(
items: I,
sample: usize,
) -> Result<SerializeSource<I::IntoIter>, DataError>
where
T: Serialize,
I: IntoIterator<Item = T>,
{
RecordSource::new(Records::new(items.into_iter()), sample)
}
pub type SerializeSource<I> = RecordSource<Records<I>>;
#[derive(Debug)]
pub struct Records<I> {
items: I,
index: usize,
}
impl<I> Records<I> {
pub fn new(items: I) -> Self {
Records { items, index: 0 }
}
}
impl<T: Serialize, I: Iterator<Item = T>> Iterator for Records<I> {
type Item = Result<Json, DataError>;
fn next(&mut self) -> Option<Self::Item> {
let item = self.items.next()?;
self.index += 1;
Some(serde_json::to_value(item).map_err(|e| DataError::at(self.index, e.to_string())))
}
}
#[cfg(test)]
mod tests {
use std::collections::BTreeMap;
use super::*;
use crate::Value;
#[test]
fn maps_and_scalars_become_rows() {
let rows = read([BTreeMap::from([("b", 2), ("a", 1)])]).unwrap();
assert_eq!(rows.columns(), ["a", "b"]);
let rows = read([1.5, 2.0]).unwrap();
assert_eq!(rows.columns(), ["value"]);
assert_eq!(rows.rows()[0], [Value::Float(1.5)]);
}
#[test]
fn errors_name_the_record() {
let bad = BTreeMap::from([((1, 2), 3)]);
let error = read([bad]).unwrap_err();
assert_eq!(error.line(), Some(1));
let mut source = source(Vec::<u8>::new()).unwrap();
assert!(source.next_row().is_none());
}
}