From e7a6e3101564ba69dd85284fdace774466653b90 Mon Sep 17 00:00:00 2001 From: Piv <18462828+Piv200@users.noreply.github.com> Date: Sat, 29 Jul 2023 15:02:45 +0930 Subject: [PATCH] Add some notes on customising reader/deserialiser to use one other than csv that interops with serde. --- src/filter.rs | 6 +--- src/io.rs | 83 ++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 60 insertions(+), 29 deletions(-) diff --git a/src/filter.rs b/src/filter.rs index a5d3b9c..6ccffa1 100644 --- a/src/filter.rs +++ b/src/filter.rs @@ -1,8 +1,4 @@ -use std::{ - collections::HashMap, - io::{Read, Write}, - str::FromStr, -}; +use std::{collections::HashMap, io::Read, str::FromStr}; use crate::io::RecordSerializer; diff --git a/src/io.rs b/src/io.rs index 36d422c..cc08db2 100644 --- a/src/io.rs +++ b/src/io.rs @@ -1,12 +1,7 @@ -use std::{ - collections::HashMap, - io::{Read, Write}, -}; +use std::io::{Read, Write}; -use anyhow::bail; -use csv::DeserializeRecordsIter; use rmp_serde::{Deserializer, Serializer}; -use serde::{de::DeserializeOwned, Serialize}; +use serde::{Deserialize, Serialize}; pub trait RecordSerializer { fn serialize(&mut self, record: impl Serialize) -> anyhow::Result<()>; @@ -26,28 +21,68 @@ impl RecordSerializer for Serializer { } } -// TODO: Want to be able to deserialise with serde over a reader like we currently do with the writer -// pub trait RecordDeserializer>> { -// fn deserialize(&mut self) -> I; +// // pub struct RecordDeserializerIterWrapper< +// // D: DeserializeOwned, +// // I: Iterator>, +// // > { +// // pub inner: I, +// // } + +// // impl>> Iterator +// // for RecordDeserializerIterWrapper +// // { +// // type Item = Result; + +// // fn next(&mut self) -> Option { +// // self.inner.next() +// // } +// // } + +// // This person has the same issue as me (it's exactly the same, just with different serde implementations) +// // https://stackoverflow.com/questions/69691366/using-serde-for-two-deserialization-formats + +// // impl + +// // TODO: Want to be able to deserialise with serde over a reader like we currently do with the writer (rather than forcing to deserialize to a hashmap) +// // However, this doesn't really work when returning an arbitrary iterator, so the iterator should be specific, like what's done in + +// // This from rust messagepack is basically what I'm looking for? Would prefer to be an iterator but might still work? +// // https://github.com/3Hren/msgpack-rust/blob/master/rmp-serde/src/decode.rs#L1017 +// // I think what might be possible is to have a struct for messagepack that wraps the deserializer, implements the iter trait (for result deserializeowned), +// // then just always return that struct (avoids the issues of returning an arbitrary trait). Really something like I did with RecordSerializer would be the best +// // But the problem is I can't easily return arbitrary iterators without boxing (then specifying what I'm returning anyway), really in java the implementing +// // class could return whatever implementation it wants... +// // Maybe I just create a custom deserializer that implements Deserializer for both csv and msgpack? Then just return the struct? Seems like +// // the opposite of recordserializer though which is kind of annoying. + +// // Really what I would like is to be able to just pass a deserializer, but the issues is csv doesn't export its deserializer (though it does have an implementation) +// // Actually it's even more complex than that, as I want to also be able to seek in the underlying reader somehow, I think this'll only be supported by +// // csv though? For now just leave it and stick with csv reading instead + +// pub trait RecordDeserializer { +// // TODO: Don't do this, deserializer is for messagepack only, want it to easily support other deserializers +// fn deserializeT>(&mut self) -> Result; // } -// impl>> -// RecordDeserializer for csv::Reader -// { -// fn deserialize(&mut self) -> I { -// self.deserialize().into_iter().map(|r| match r { -// Ok(ok) => Ok(ok), -// Err(err) => bail!(err), -// }) -// } -// } +// // impl RecordDeserializer for csv::Reader { +// // fn deserialize( +// // &mut self, +// // ) -> Box>> { +// // Box::new(self.deserialize().into_iter().map(|r| match r { +// // Ok(ok) => Ok(ok), +// // Err(err) => bail!(err), +// // })) +// // } +// // } // impl RecordDeserializer for Deserializer { -// fn deserialize(&mut self) -> I +// fn deserializeT<'de, D>(&mut self) -> Result // where -// D: DeserializeOwned, -// I: Iterator, +// D: Deserialize<'de>, // { -// todo!() +// match Deserialize::deserialize(self) { +// Ok(ok) => Ok(ok), +// Err(e) => Err(anyhow::Error::from(e)), +// } // } // }