1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
use serde::{Serialize, Deserialize}; use std::io::{Write, Seek, SeekFrom}; use std::os::windows::fs::FileExt; type Result<T> = std::result::Result<T, std::io::Error>; pub struct IncrementalJsonWriter<T: FileExt + Write + Seek> { buffer: T, } impl<T: FileExt + Write + Seek> IncrementalJsonWriter<T> { pub fn new(buffer: T) -> Self { IncrementalJsonWriter::<T> { buffer } } pub fn write_json<U: Serialize>(&mut self, element: &U) -> Result<usize> { self.write(serde_json::to_string_pretty(&element)?.as_bytes()) } } impl<T: FileExt + Write + Seek> Write for IncrementalJsonWriter<T> { fn write(&mut self, element: &[u8]) -> Result<usize> { let mut current = self.buffer.seek(SeekFrom::Current(0))?; let mut bytes = vec![]; if current == 0 { self.buffer.write(b"[\n\n]")?; current = self.buffer.seek(SeekFrom::Current(0))?; } else { bytes.extend(b",\n"); } bytes.extend(element); bytes.push(b'\n'); bytes.push(b']'); self.buffer.seek_write(&bytes, current - 2) } fn flush(&mut self) -> Result<()> { self.buffer.flush() } } #[test] fn writer_writes_square_brackets_to_buffer() { use std::io::{Read}; let expect_one = String::from("[\n{\n \"name\": \"Test\",\n \"detail\": 0\n},\ \n{\n \"name\": \"Test\",\n \"detail\": 1\n}\n]"); let expect_two = String::from("[\n{\n \"name\": \"Test\",\n \"detail\": 0\n},\ \n{\n \"name\": \"Test\",\n \"detail\": 1\n},\ \n{\n \"name\": \"Test\",\n \"detail\": 2\n},\ \n{\n \"name\": \"Test\",\n \"detail\": 3\n}\n]"); let path = "testfile.json"; let rows: Vec<Record> = vec![0, 1, 2, 3] .iter() .map(|num| Record { name: String::from("Test"), detail: *num}) .collect(); let writer = std::fs::File::create(path).unwrap(); let mut json_writer = IncrementalJsonWriter::new(writer); let mut reader = std::fs::File::open(path).unwrap(); for row in rows.iter().take(2) { json_writer.write_json(&row).unwrap(); } let mut buffer = String::new(); reader.read_to_string(&mut buffer).unwrap(); assert_eq!(expect_one, buffer); for row in rows.iter().skip(2).take(2) { json_writer.write_json(&row).unwrap(); } let mut buffer = String::new(); reader.seek(SeekFrom::Start(0)).unwrap(); reader.read_to_string(&mut buffer).unwrap(); assert_eq!(expect_two, buffer); } #[derive(Serialize, Deserialize, Debug)] struct Record { name: String, detail: u32 }