From 46603a5f187eb141e29613895e8777fe2e30e26b Mon Sep 17 00:00:00 2001 From: Kamil Koczurek Date: Sat, 11 Jun 2022 16:39:42 +0200 Subject: [PATCH] fj: make fj build with the "serialization" feature This required 3 changes: 1. Import serde::{Serialize, Deserialize}. 2. Implement {Serialize, Deserialize} for Sketch. 3. Enable the "derive" feature for serde. --- crates/fj/Cargo.toml | 2 +- crates/fj/src/angle.rs | 2 ++ crates/fj/src/lib.rs | 2 ++ crates/fj/src/shape_2d.rs | 49 ++++++++++++++++++++++++++++++++++++++- crates/fj/src/shape_3d.rs | 2 ++ 5 files changed, 55 insertions(+), 2 deletions(-) diff --git a/crates/fj/Cargo.toml b/crates/fj/Cargo.toml index b197605e6..40e7e8f08 100644 --- a/crates/fj/Cargo.toml +++ b/crates/fj/Cargo.toml @@ -16,7 +16,7 @@ default = [] serialization = ["serde"] [dependencies] -serde = { version = "1.0.7", optional = true } +serde = { version = "1.0.7", features = ["derive"], optional = true } [dependencies.fj-proc] path = "../../crates/fj-proc" \ No newline at end of file diff --git a/crates/fj/src/angle.rs b/crates/fj/src/angle.rs index 5345f9cec..f858dcc98 100644 --- a/crates/fj/src/angle.rs +++ b/crates/fj/src/angle.rs @@ -1,3 +1,5 @@ +#[cfg(feature = "serialization")] +use serde::{Deserialize, Serialize}; use std::f64::consts::{PI, TAU}; // One gon in radians diff --git a/crates/fj/src/lib.rs b/crates/fj/src/lib.rs index c6cdb061d..8377b6178 100644 --- a/crates/fj/src/lib.rs +++ b/crates/fj/src/lib.rs @@ -26,6 +26,8 @@ mod shape_3d; pub use self::{angle::*, shape_2d::*, shape_3d::*}; pub use fj_proc::*; +#[cfg(feature = "serialization")] +use serde::{Deserialize, Serialize}; /// A shape #[derive(Clone, Debug)] diff --git a/crates/fj/src/shape_2d.rs b/crates/fj/src/shape_2d.rs index 0694d87a2..fe7ff371c 100644 --- a/crates/fj/src/shape_2d.rs +++ b/crates/fj/src/shape_2d.rs @@ -1,3 +1,5 @@ +#[cfg(feature = "serialization")] +use serde::{de, ser, Deserialize, Serialize}; use std::mem; use std::sync::atomic; @@ -130,7 +132,6 @@ impl From for Shape2d { /// that the edges are non-overlapping. If you create a `Sketch` with /// overlapping edges, you're on your own. #[derive(Debug)] -#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))] #[repr(C)] pub struct Sketch { // The fields are the raw parts of a `Vec`. `Sketch` needs to be FFI-safe, @@ -249,6 +250,52 @@ impl Drop for Sketch { } } +/// An owned, non-repr-C Sketch +/// +/// De/serializing a non-trivial structure with raw pointers is a hassle. +/// This structure is a simple, owned intermediate form that can use the derive +/// macros provided by serde. The implementation of the Serialize and Deserialize +/// traits for Sketch use this type as a stepping stone. +/// +/// Note that constructing this requires cloning the points behind Sketch. If +/// de/serialization turns out to be a bottleneck, a more complete implementation +/// will be required. +#[cfg(feature = "serialization")] +#[derive(Serialize, Deserialize)] +#[serde(rename = "Sketch")] +struct SerdeSketch { + points: Vec<[f64; 2]>, + color: [u8; 4], +} + +#[cfg(feature = "serialization")] +impl ser::Serialize for Sketch { + fn serialize(&self, serializer: S) -> Result + where + S: ser::Serializer, + { + let serde_sketch = SerdeSketch { + points: self.to_points(), + color: self.color, + }; + + serde_sketch.serialize(serializer) + } +} + +#[cfg(feature = "serialization")] +impl<'de> de::Deserialize<'de> for Sketch { + fn deserialize(deserializer: D) -> Result + where + D: de::Deserializer<'de>, + { + SerdeSketch::deserialize(deserializer).map(|serde_sketch| { + Sketch::from_points(serde_sketch.points) + .with_color(serde_sketch.color) + }) + } +} + impl From for Shape { fn from(shape: Sketch) -> Self { Self::Shape2d(shape.into()) diff --git a/crates/fj/src/shape_3d.rs b/crates/fj/src/shape_3d.rs index 2376fa157..2e41f8151 100644 --- a/crates/fj/src/shape_3d.rs +++ b/crates/fj/src/shape_3d.rs @@ -1,4 +1,6 @@ use crate::{Angle, Shape, Shape2d}; +#[cfg(feature = "serialization")] +use serde::{Deserialize, Serialize}; /// A 3-dimensional shape #[derive(Clone, Debug)]