Skip to content

Add serde behind feature flag for some builtins #237

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/full-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,11 @@ jobs:
godot-binary: godot.linuxbsd.editor.dev.double.x86_64
rust-extra-args: --features double-precision

- name: linux-threads
- name: linux-features
os: ubuntu-20.04
artifact-name: linux
godot-binary: godot.linuxbsd.editor.dev.x86_64
rust-extra-args: --features threads
rust-extra-args: --features threads,serde

- name: linux-nightly
os: ubuntu-20.04
Expand Down
2 changes: 2 additions & 0 deletions godot-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ godot-ffi = { path = "../godot-ffi" }

# See https://docs.rs/glam/latest/glam/index.html#feature-gates
glam = { version = "0.23", features = ["debug-glam-assert"] }
serde = { version = "1", features = ["derive"], optional = true }

# Reverse dev dependencies so doctests can use `godot::` prefix
[dev-dependencies]
godot = { path = "../godot" }
serde_json = "1.0"

[build-dependencies]
godot-codegen = { path = "../godot-codegen" }
13 changes: 13 additions & 0 deletions godot-core/src/builtin/aabb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use super::Vector3;
///
/// The 2D counterpart to `Aabb` is [`Rect2`](super::Rect2).
#[derive(Default, Copy, Clone, PartialEq, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
pub struct Aabb {
pub position: Vector3,
Expand Down Expand Up @@ -101,3 +102,15 @@ impl std::fmt::Display for Aabb {
unsafe impl GodotFfi for Aabb {
ffi_methods! { type sys::GDExtensionTypePtr = *mut Self; .. }
}

#[cfg(test)]
mod test {
#[cfg(feature = "serde")]
#[test]
fn serde_roundtrip() {
let aabb = super::Aabb::default();
let expected_json = "{\"position\":{\"x\":0.0,\"y\":0.0,\"z\":0.0},\"size\":{\"x\":0.0,\"y\":0.0,\"z\":0.0}}";

crate::builtin::test_utils::roundtrip(&aabb, expected_json);
}
}
10 changes: 10 additions & 0 deletions godot-core/src/builtin/basis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use super::{real, RMat3, RQuat, RVec2, RVec3};
/// The basis vectors are the columns of the matrix, whereas the [`rows`](Self::rows) field represents
/// the row vectors.
#[derive(Copy, Clone, PartialEq, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
pub struct Basis {
/// The rows of the matrix. These are *not* the basis vectors.
Expand Down Expand Up @@ -835,4 +836,13 @@ mod test {
"Basis with three components infinite should not be finite."
);
}

#[cfg(feature = "serde")]
#[test]
fn serde_roundtrip() {
let basis = Basis::IDENTITY;
let expected_json = "{\"rows\":[{\"x\":1.0,\"y\":0.0,\"z\":0.0},{\"x\":0.0,\"y\":1.0,\"z\":0.0},{\"x\":0.0,\"y\":0.0,\"z\":1.0}]}";

crate::builtin::test_utils::roundtrip(&basis, expected_json);
}
}
13 changes: 13 additions & 0 deletions godot-core/src/builtin/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use sys::{ffi_methods, GodotFfi};
/// values outside this range are explicitly allowed for e.g. High Dynamic Range (HDR).
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Color {
/// The color's red component.
pub r: f32,
Expand Down Expand Up @@ -511,3 +512,15 @@ impl std::fmt::Display for Color {
write!(f, "({}, {}, {}, {})", self.r, self.g, self.b, self.a)
}
}

#[cfg(test)]
mod test {
#[cfg(feature = "serde")]
#[test]
fn serde_roundtrip() {
let color = super::Color::WHITE;
let expected_json = "{\"r\":1.0,\"g\":1.0,\"b\":1.0,\"a\":1.0}";

crate::builtin::test_utils::roundtrip(&color, expected_json);
}
}
19 changes: 19 additions & 0 deletions godot-core/src/builtin/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -407,3 +407,22 @@ mod export {
// TODO investigate whether Signal should impl Export at all, and if so, how
// impl_export_by_clone!(Signal);
}

#[cfg(all(test, feature = "serde"))]
pub(crate) mod test_utils {
use serde::{Deserialize, Serialize};

pub(crate) fn roundtrip<T>(value: &T, expected_json: &str)
where
T: for<'a> Deserialize<'a> + Serialize + PartialEq + std::fmt::Debug,
{
let json: String = serde_json::to_string(value).unwrap();
let back: T = serde_json::from_str(json.as_str()).unwrap();

assert_eq!(back, *value, "serde round-trip changes value");
assert_eq!(
json, expected_json,
"value does not conform to expected JSON"
);
}
}
13 changes: 13 additions & 0 deletions godot-core/src/builtin/plane.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use super::{is_equal_approx, real, Vector3};
/// unit length and will panic if this invariant is violated. This is not separately
/// annotated for each method.
#[derive(Copy, Clone, PartialEq, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
pub struct Plane {
pub normal: Vector3,
Expand Down Expand Up @@ -189,4 +190,16 @@ mod test {
Vector3::new(0.0, 0.0, 2.0),
);
}

#[cfg(feature = "serde")]
#[test]
fn serde_roundtrip() {
let plane = Plane {
normal: Vector3::ONE,
d: 0.0,
};
let expected_json = "{\"normal\":{\"x\":1.0,\"y\":1.0,\"z\":1.0},\"d\":0.0}";

crate::builtin::test_utils::roundtrip(&plane, expected_json);
}
}
10 changes: 10 additions & 0 deletions godot-core/src/builtin/projection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use super::{real, RMat4, RealConv};
/// Note: The current implementation largely makes calls to godot for its
/// methods and as such are not as performant as other types.
#[derive(Copy, Clone, PartialEq, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
pub struct Projection {
/// The columns of the projection matrix.
Expand Down Expand Up @@ -960,6 +961,15 @@ mod test {
}
}
}

#[cfg(feature = "serde")]
#[test]
fn serde_roundtrip() {
let projection = Projection::IDENTITY;
let expected_json = "{\"cols\":[{\"x\":1.0,\"y\":0.0,\"z\":0.0,\"w\":0.0},{\"x\":0.0,\"y\":1.0,\"z\":0.0,\"w\":0.0},{\"x\":0.0,\"y\":0.0,\"z\":1.0,\"w\":0.0},{\"x\":0.0,\"y\":0.0,\"z\":0.0,\"w\":1.0}]}";

crate::builtin::test_utils::roundtrip(&projection, expected_json);
}
}

impl std::fmt::Display for Projection {
Expand Down
13 changes: 13 additions & 0 deletions godot-core/src/builtin/quaternion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use super::{real, RQuat};
use super::{Basis, EulerOrder};

#[derive(Copy, Clone, PartialEq, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
pub struct Quaternion {
pub x: real,
Expand Down Expand Up @@ -347,3 +348,15 @@ impl Neg for Quaternion {
Self::new(-self.x, -self.y, -self.z, -self.w)
}
}

#[cfg(test)]
mod test {
#[cfg(feature = "serde")]
#[test]
fn serde_roundtrip() {
let quaternion = super::Quaternion::new(1.0, 1.0, 1.0, 1.0);
let expected_json = "{\"x\":1.0,\"y\":1.0,\"z\":1.0,\"w\":1.0}";

crate::builtin::test_utils::roundtrip(&quaternion, expected_json);
}
}
13 changes: 13 additions & 0 deletions godot-core/src/builtin/rect2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use super::{real, Rect2i, Vector2};
///
/// The 3D counterpart to `Rect2` is [`Aabb`](super::Aabb).
#[derive(Default, Copy, Clone, PartialEq, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
pub struct Rect2 {
pub position: Vector2,
Expand Down Expand Up @@ -125,3 +126,15 @@ impl std::fmt::Display for Rect2 {
write!(f, "[P: {}, S: {}]", self.position, self.size)
}
}

#[cfg(test)]
mod test {
#[cfg(feature = "serde")]
#[test]
fn serde_roundtrip() {
let rect = super::Rect2::default();
let expected_json = "{\"position\":{\"x\":0.0,\"y\":0.0},\"size\":{\"x\":0.0,\"y\":0.0}}";

crate::builtin::test_utils::roundtrip(&rect, expected_json);
}
}
10 changes: 10 additions & 0 deletions godot-core/src/builtin/rect2i.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use super::{Rect2, RectSide, Vector2i};
/// `Rect2i` consists of a position, a size, and several utility functions. It is typically used for
/// fast overlap tests.
#[derive(Default, Copy, Clone, Eq, PartialEq, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
pub struct Rect2i {
/// The position of the rectangle.
Expand Down Expand Up @@ -583,4 +584,13 @@ mod test {
let rect = Rect2i::from_components(0, 0, -5, -5);
Rect2i::default().merge(rect);
}

#[cfg(feature = "serde")]
#[test]
fn serde_roundtrip() {
let rect = Rect2i::default();
let expected_json = "{\"position\":{\"x\":0,\"y\":0},\"size\":{\"x\":0,\"y\":0}}";

crate::builtin::test_utils::roundtrip(&rect, expected_json);
}
}
10 changes: 10 additions & 0 deletions godot-core/src/builtin/transform2d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use super::{real, RAffine2, RMat2};
///
/// For methods that don't take translation into account, see [`Basis2D`].
#[derive(Default, Copy, Clone, PartialEq, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
pub struct Transform2D {
/// The first basis vector.
Expand Down Expand Up @@ -739,4 +740,13 @@ mod test {
"let with: Transform2D three components infinite should not be finite.",
);
}

#[cfg(feature = "serde")]
#[test]
fn serde_roundtrip() {
let transform = Transform2D::default();
let expected_json = "{\"a\":{\"x\":0.0,\"y\":0.0},\"b\":{\"x\":0.0,\"y\":0.0},\"origin\":{\"x\":0.0,\"y\":0.0}}";

crate::builtin::test_utils::roundtrip(&transform, expected_json);
}
}
10 changes: 10 additions & 0 deletions godot-core/src/builtin/transform3d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use super::{Aabb, Basis, Plane, Projection, Vector3};
/// [ a.z b.z c.z o.z ]
/// ```
#[derive(Default, Copy, Clone, PartialEq, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
pub struct Transform3D {
/// The basis is a matrix containing 3 vectors as its columns. They can be
Expand Down Expand Up @@ -459,4 +460,13 @@ mod test {
"Transform3D with two components infinite should not be finite.",
);
}

#[cfg(feature = "serde")]
#[test]
fn serde_roundtrip() {
let transform = Transform3D::default();
let expected_json = "{\"basis\":{\"rows\":[{\"x\":1.0,\"y\":0.0,\"z\":0.0},{\"x\":0.0,\"y\":1.0,\"z\":0.0},{\"x\":0.0,\"y\":0.0,\"z\":1.0}]},\"origin\":{\"x\":0.0,\"y\":0.0,\"z\":0.0}}";

crate::builtin::test_utils::roundtrip(&transform, expected_json);
}
}
10 changes: 10 additions & 0 deletions godot-core/src/builtin/vector2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use super::{real, RAffine2, RVec2};
///
/// See [`Vector2i`] for its integer counterpart.
#[derive(Debug, Default, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
pub struct Vector2 {
/// The vector's X component.
Expand Down Expand Up @@ -369,4 +370,13 @@ mod test {
Vector2::is_equal_approx
);
}

#[cfg(feature = "serde")]
#[test]
fn serde_roundtrip() {
let vector = Vector2::default();
let expected_json = "{\"x\":0.0,\"y\":0.0}";

crate::builtin::test_utils::roundtrip(&vector, expected_json);
}
}
10 changes: 10 additions & 0 deletions godot-core/src/builtin/vector2i.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use super::IVec2;
/// configured with an engine build option. Use `i64` or [`PackedInt64Array`] if 64-bit values are
/// needed.
#[derive(Debug, Default, Clone, Copy, Eq, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
pub struct Vector2i {
/// The vector's X component.
Expand Down Expand Up @@ -140,4 +141,13 @@ mod test {
assert_eq!(a.coord_min(b), Vector2i::new(0, 3));
assert_eq!(a.coord_max(b), Vector2i::new(1, 5));
}

#[cfg(feature = "serde")]
#[test]
fn serde_roundtrip() {
let vector = Vector2i::default();
let expected_json = "{\"x\":0,\"y\":0}";

crate::builtin::test_utils::roundtrip(&vector, expected_json);
}
}
10 changes: 10 additions & 0 deletions godot-core/src/builtin/vector3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use super::{real, Basis, RVec3};
///
/// See [`Vector3i`] for its integer counterpart.
#[derive(Debug, Default, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
pub struct Vector3 {
/// The vector's X component.
Expand Down Expand Up @@ -432,4 +433,13 @@ mod test {
Vector3::is_equal_approx
);
}

#[cfg(feature = "serde")]
#[test]
fn serde_roundtrip() {
let vector = Vector3::default();
let expected_json = "{\"x\":0.0,\"y\":0.0,\"z\":0.0}";

crate::builtin::test_utils::roundtrip(&vector, expected_json);
}
}
10 changes: 10 additions & 0 deletions godot-core/src/builtin/vector3i.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use super::IVec3;
/// configured with an engine build option. Use `i64` or [`PackedInt64Array`] if 64-bit values are
/// needed.
#[derive(Debug, Default, Clone, Copy, Eq, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
pub struct Vector3i {
/// The vector's X component.
Expand Down Expand Up @@ -151,4 +152,13 @@ mod test {
assert_eq!(a.coord_min(b), Vector3i::new(0, 3, 2));
assert_eq!(a.coord_max(b), Vector3i::new(1, 5, 5));
}

#[cfg(feature = "serde")]
#[test]
fn serde_roundtrip() {
let vector = Vector3i::default();
let expected_json = "{\"x\":0,\"y\":0,\"z\":0}";

crate::builtin::test_utils::roundtrip(&vector, expected_json);
}
}
10 changes: 10 additions & 0 deletions godot-core/src/builtin/vector4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use super::{real, RVec4};
///
/// See [`Vector4i`] for its integer counterpart.
#[derive(Debug, Default, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
pub struct Vector4 {
/// The vector's X component.
Expand Down Expand Up @@ -160,4 +161,13 @@ mod test {
Vector4::is_equal_approx
);
}

#[cfg(feature = "serde")]
#[test]
fn serde_roundtrip() {
let vector = Vector4::default();
let expected_json = "{\"x\":0.0,\"y\":0.0,\"z\":0.0,\"w\":0.0}";

crate::builtin::test_utils::roundtrip(&vector, expected_json);
}
}
Loading