|
| 1 | +use crate::schema::Schema; |
| 2 | +use serde_json::Value; |
| 3 | +use std::collections::BTreeMap; |
| 4 | +use std::io::{self, BufReader, BufRead}; |
| 5 | +use std::fs::File; |
| 6 | + |
| 7 | +pub struct JSTable { |
| 8 | + pub schema: Schema, |
| 9 | + pub documents: BTreeMap<String, Value>, |
| 10 | +} |
| 11 | + |
| 12 | +pub fn read_jstable(path: &str) -> io::Result<JSTable> { |
| 13 | + let file = File::open(path)?; |
| 14 | + let reader = BufReader::new(file); |
| 15 | + let mut lines = reader.lines(); |
| 16 | + |
| 17 | + let schema_line = lines.next().ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "Missing schema line"))??; |
| 18 | + let schema: Schema = serde_json::from_str(&schema_line)?; |
| 19 | + |
| 20 | + let mut documents = BTreeMap::new(); |
| 21 | + for line_result in lines { |
| 22 | + let line = line_result?; |
| 23 | + let record: (String, Value) = serde_json::from_str(&line)?; |
| 24 | + documents.insert(record.0, record.1); |
| 25 | + } |
| 26 | + |
| 27 | + Ok(JSTable { schema, documents }) |
| 28 | +} |
| 29 | + |
| 30 | +#[cfg(test)] |
| 31 | +mod tests { |
| 32 | + use super::*; |
| 33 | + use crate::schema::SchemaType; |
| 34 | + use serde_json::json; |
| 35 | + use tempfile::NamedTempFile; |
| 36 | + use std::io::Write; |
| 37 | + |
| 38 | + #[test] |
| 39 | + fn test_read_jstable() -> Result<(), Box<dyn std::error::Error>> { |
| 40 | + let mut file = NamedTempFile::new().unwrap(); |
| 41 | + let schema_json = serde_json::to_string(&Schema { |
| 42 | + types: vec![SchemaType::Object], |
| 43 | + properties: Some(BTreeMap::from([ |
| 44 | + ("a".to_string(), Schema::new(SchemaType::Integer)), |
| 45 | + ])), |
| 46 | + items: None, |
| 47 | + }).unwrap(); |
| 48 | + writeln!(file, "{}", schema_json).unwrap(); |
| 49 | + writeln!(file, "{}", serde_json::to_string(&json!(["id1", {"a": 1}]))?).unwrap(); |
| 50 | + writeln!(file, "{}", serde_json::to_string(&json!(["id2", {"a": 2}]))?).unwrap(); |
| 51 | + |
| 52 | + let jstable = read_jstable(file.path().to_str().unwrap()).unwrap(); |
| 53 | + |
| 54 | + assert_eq!(jstable.schema.types, vec![SchemaType::Object]); |
| 55 | + assert_eq!(jstable.documents.len(), 2); |
| 56 | + assert_eq!(*jstable.documents.get("id1").unwrap(), json!({"a": 1})); |
| 57 | + assert_eq!(*jstable.documents.get("id2").unwrap(), json!({"a": 2})); |
| 58 | + Ok(()) |
| 59 | + } |
| 60 | +} |
0 commit comments