I'm writing an encoder for PostgreSQL binary protocol (which is used in a COPY WITH BINARY
command for example). Among a few types that can be mapped to the Serde types (ex. smallint
is the same as i16
and so on), PostgreSQL has some types that can be mapped only to external crate structs, let's say, timestamp with time zone
can be mapped to chrono::DateTime<Tz>
.
While chrono
provides an implementation for serde::Serialize
for DateTime<Tz>
type, it can't be used in my format, because instead of writing a string I'm required to write the microseconds amount starting from the 2000-00-00T00:00:00+00:00
; therefore default serde::Serialize
implementation is not suitable for me.
Another example is a MAC address, which in Rust can be a [u8; 6]
, eui48::MacAddress
or smth else.
The first option that I saw is to provide a bunch of functions for #[serde(with)]
attribute and force end user to use them where needed, but I'll get access only to S: Serializer
trait object, not to my Serializer
type or an inner Encoder
and will not be able to write bytes directly (Serializer::serialize_*
methods will not help here).
The second option is to use Serde "remote derive" feature and serialize object directly to bytes array, but it will require for user to add #[serde(with)]
attribute whenever it is needed and will lead to a huge code amount to support. Also, it might just not work, I had not investigated this feature closely
Right now I have a bunch of traits which are utilized by the low-level encoder, but I don't think I'll be able to re-use them in any way with Serializer.
So, is there anything that I'm missing or serde just not suitable right now for my requirements?