1use serde::Serialize;
28use serde_json::Value as Json;
29
30use crate::{DataError, RecordSource, RowSource, Rows};
31
32pub use crate::record::DEFAULT_SAMPLE;
33
34pub fn read<T: Serialize>(items: impl IntoIterator<Item = T>) -> Result<Rows, DataError> {
36 RecordSource::new(Records::new(items.into_iter()), usize::MAX)?.collect_rows()
37}
38
39pub fn source<T, I>(items: I) -> Result<SerializeSource<I::IntoIter>, DataError>
42where
43 T: Serialize,
44 I: IntoIterator<Item = T>,
45{
46 source_with_sample(items, DEFAULT_SAMPLE)
47}
48
49pub fn source_with_sample<T, I>(
51 items: I,
52 sample: usize,
53) -> Result<SerializeSource<I::IntoIter>, DataError>
54where
55 T: Serialize,
56 I: IntoIterator<Item = T>,
57{
58 RecordSource::new(Records::new(items.into_iter()), sample)
59}
60
61pub type SerializeSource<I> = RecordSource<Records<I>>;
63
64#[derive(Debug)]
66pub struct Records<I> {
67 items: I,
68 index: usize,
69}
70
71impl<I> Records<I> {
72 pub fn new(items: I) -> Self {
74 Records { items, index: 0 }
75 }
76}
77
78impl<T: Serialize, I: Iterator<Item = T>> Iterator for Records<I> {
79 type Item = Result<Json, DataError>;
80
81 fn next(&mut self) -> Option<Self::Item> {
82 let item = self.items.next()?;
83 self.index += 1;
84 Some(serde_json::to_value(item).map_err(|e| DataError::at(self.index, e.to_string())))
85 }
86}
87
88#[cfg(test)]
89mod tests {
90 use std::collections::BTreeMap;
91
92 use super::*;
93 use crate::Value;
94
95 #[test]
96 fn maps_and_scalars_become_rows() {
97 let rows = read([BTreeMap::from([("b", 2), ("a", 1)])]).unwrap();
98 assert_eq!(rows.columns(), ["a", "b"]);
99 let rows = read([1.5, 2.0]).unwrap();
100 assert_eq!(rows.columns(), ["value"]);
101 assert_eq!(rows.rows()[0], [Value::Float(1.5)]);
102 }
103
104 #[test]
105 fn errors_name_the_record() {
106 let bad = BTreeMap::from([((1, 2), 3)]);
108 let error = read([bad]).unwrap_err();
109 assert_eq!(error.line(), Some(1));
110 let mut source = source(Vec::<u8>::new()).unwrap();
111 assert!(source.next_row().is_none());
112 }
113}