-
Notifications
You must be signed in to change notification settings - Fork 3
Description
Currently, the Encodable
trait is generic over E: Encoder
, allowing the encodable to effectively choose which encoders it supports. I find that a bit strange since I'd say an encodable value shouldn't really care about what encoder will write its bytes (or where or how), and instead only concern itself about how to convert &self
into said bytes. And indeed, as far as I can tell, all encodables appear to just do impl<E: Encoder> Encodable<E> for SomeEncodable
anyway. At least all in this repository and the ones I've written so far.
Implementing just Encodable<SomeEncoder>
and Encodable<OtherEncoder>
, for instance, not only leaves out all the other encoders (which is a shame), but also introduces a hazard as the two implementations may accidentally differ.
I'm wondering… Why can't all encodables support all encoders? We could do that by moving the generic parameter onto the encode
method, thus allowing the caller to choose the encoder. I haven't tested this but I think something like this could work:
pub trait Encodable {
type Error<EncoderError>: From<EncoderError>;
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), Self::Error<E::Error>>;
}
This would also completely remove the need for trait EncodableSize: Encodable<encoders::SizeEncoder>
as all encodables would automatically support the SizeEncoder
, which to me makes sense.
Note that serde
's Serialize
trait has a generic method like this as well which matches the sentiment here: a Serialize
struct shouldn't have to know or worry about json/yaml/whatever.
If I were to contribute a pull request, would there be interest in merging it or is that already too disruptive a change?