use enum_dispatch::enum_dispatch; use serde::{Deserialize, Serialize}; #[enum_dispatch] trait Shaped { fn area(&self) -> f32; } #[enum_dispatch(Shaped)] #[derive(Serialize, Deserialize, Debug, PartialEq)] enum Shape { Rectangle, Square, Circle, } #[derive(Serialize, Deserialize, Debug, PartialEq)] struct Rectangle { w: f32, h: f32, } impl Shaped for Rectangle { fn area(&self) -> f32 { self.w * self.h } } #[derive(Serialize, Deserialize, Debug, PartialEq)] struct Square { s: f32, } impl Shaped for Square { fn area(&self) -> f32 { self.s * self.s } } #[derive(Serialize, Deserialize, Debug, PartialEq)] struct Circle { r: f32, } impl Shaped for Circle { fn area(&self) -> f32 { self.r * self.r * std::f32::consts::PI } } #[test] fn through_serde() { let rectangle = Rectangle { w: 10., h: 20. }.into(); let square = Square { s: 15. }.into(); let circle = Circle { r: 10. }.into(); let shapes: Vec = vec![rectangle, square, circle]; let serialized_shapes: Vec = shapes .iter() .map(|s| serde_json::to_string(&s).unwrap()) .collect(); assert_eq!( serialized_shapes, [ "{\"Rectangle\":{\"w\":10.0,\"h\":20.0}}", "{\"Square\":{\"s\":15.0}}", "{\"Circle\":{\"r\":10.0}}" ] ); let deserialized_shapes: Vec = serialized_shapes .iter() .map(|s| serde_json::from_str(&s).unwrap()) .collect(); for (shape, new_shape) in shapes.iter().zip(deserialized_shapes.iter()) { assert_eq!(shape, new_shape); } }