I'm implementing a custom trait for several of my structs, but I think writing out impl MySerialize for StructX {}
for every struct doesn't seem very efficient. I know I can derive it as a custom trait, but writing a proc macro requires a new crate, which I don't want to use. Is there a way I can put it into the struct's method implementation block i.e., the impl StructX
block?
Also just looking for general suggestions on this topic since I'm pretty new to custom trait implementations.
use bincode2;
use serde::{Serialize as SerdeSerialize, Deserialize as SerdeDeserialize};
pub trait MySerialize {
fn to_bytes(&self) -> Result<Vec<u8>, String>
where
Self: SerdeSerialize
{
let serialized = bincode2::config().
serialize(&self).
unwrap();
Ok(serialized)
}
}
pub trait MyDeserialize<'de> {
fn from_bytes(buf: &'de [u8]) -> Result<Self, String>
where
Self: Sized,
Self: SerdeDeserialize<'de>
{
let deserialized: Self = bincode2::config().
deserialize(buf).
unwrap();
Ok(deserialized)
}
}
#[derive(SerdeSerialize, SerdeDeserialize, Clone, Debug, PartialEq, Eq)]
pub struct Snake {
pub route: Vec<u8>,
pub foods: [u8; 32],
}
// I don't like writing these out for every struct...
impl MySerialize for Snake {}
impl<'de> MyDeserialize<'de> for Snake {}
#[derive(SerdeSerialize, SerdeDeserialize, Clone, Debug, PartialEq, Eq)]
pub struct Ocean {
pub fishes: Vec<u8>,
pub boats: Vec<u8>,
}
// Would be nice to put this into the impl Ocean block below to clean up code
impl MySerialize for Ocean {}
impl<'de> MyDeserialize<'de> for Ocean {}
impl Ocean {
pub fn new(fishes: Vec<u8>, boats: Vec<u8>) -> Self {
Ocean {
fishes,
boats,
}
}
}
fn main() {
let ocean = Ocean::new(vec![1, 2], vec![3, 4]);
let bytes = ocean.to_bytes().unwrap();
let back_to_ocean = Ocean::from_bytes(&bytes).unwrap();
assert_eq!(ocean, back_to_ocean);
}