From c50aa4f3590871c51e7dfffa6e9a2cb2868cc04c Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Tue, 14 Jun 2016 16:02:48 +0100 Subject: [PATCH] Make the serde support behave better The previous implementation could produce illegal JSON when used with serde_json. This is a breaking change because we have to add a Clone bound on the Deserialize impls. --- Cargo.toml | 2 +- src/macros.rs | 42 ++++++++++++++++++++++++++++++++++-------- src/rect.rs | 9 +++------ src/side_offsets.rs | 1 + 4 files changed, 39 insertions(+), 15 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f3b6e6f..444b6fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "euclid" -version = "0.6.8" +version = "0.7.0" authors = ["The Servo Project Developers"] description = "Geometry primitives" documentation = "http://doc.servo.org/euclid/" diff --git a/src/macros.rs b/src/macros.rs index 38b8320..fb4f12f 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -7,8 +7,38 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +macro_rules! deserialize { + ( + { $field:ident, $($rest:tt)* } + $count:tt + { $($acc:tt)* } + $name:ident + $deserializer:ident + $T:ty + ) => ( + deserialize!( + { $($rest)* } + (1 + $count) + { $($acc)* { $field $count } } + $name + $deserializer + $T) + ); + ( + {} + $total:tt + { $({ $field:ident $index:expr })+ } + $name:ident + $deserializer:ident + $T:ty + ) => ({ + let values = try!(<[$T; $total]>::deserialize($deserializer)); + Ok($name { $($field: values[$index].clone(),)+ }) + }) +} + macro_rules! define_matrix { - ($(#[$attr:meta])* pub struct $name:ident { $(pub $field:ident: T,)+ }) => ( + ($(#[$attr:meta])* pub struct $name:ident { $(pub $field:ident: T,)+ }) => ( $(#[$attr])* #[derive(Clone, Copy, Eq, Hash, PartialEq)] pub struct $name { @@ -21,14 +51,11 @@ macro_rules! define_matrix { } } - impl ::serde::Deserialize for $name { + impl ::serde::Deserialize for $name { fn deserialize(deserializer: &mut D) -> Result where D: ::serde::Deserializer { - $(let $field = try!(T::deserialize(deserializer));)+ - Ok($name { - $($field: $field,)+ - }) + deserialize!({ $($field,)+ } 0 {} $name deserializer T) } } @@ -36,8 +63,7 @@ macro_rules! define_matrix { fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> where S: ::serde::Serializer { - $(try!(self.$field.serialize(serializer));)+ - Ok(()) + [$(&self.$field,)+].serialize(serializer) } } ) diff --git a/src/rect.rs b/src/rect.rs index bc6a4b7..93ebdc5 100644 --- a/src/rect.rs +++ b/src/rect.rs @@ -31,12 +31,11 @@ impl HeapSizeOf for Rect { } } -impl Deserialize for Rect { +impl Deserialize for Rect { fn deserialize(deserializer: &mut D) -> Result where D: Deserializer { - let origin = try!(Deserialize::deserialize(deserializer)); - let size = try!(Deserialize::deserialize(deserializer)); + let (origin, size) = try!(Deserialize::deserialize(deserializer)); Ok(Rect { origin: origin, size: size, @@ -48,9 +47,7 @@ impl Serialize for Rect { fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer { - try!(self.origin.serialize(serializer)); - try!(self.size.serialize(serializer)); - Ok(()) + (&self.origin, &self.size).serialize(serializer) } } diff --git a/src/side_offsets.rs b/src/side_offsets.rs index 76d9f47..8ccaae8 100644 --- a/src/side_offsets.rs +++ b/src/side_offsets.rs @@ -10,6 +10,7 @@ //! A group of side offsets, which correspond to top/left/bottom/right for borders, padding, //! and margins in CSS. +#[cfg(feature = "unstable")] use heapsize::HeapSizeOf; use num::Zero; use std::ops::Add;