Skip to content

Commit 172a05c

Browse files
committed
Implement serde traits for Variant types
Fix Variant serialization
1 parent 88133d7 commit 172a05c

21 files changed

+885
-1
lines changed

gdnative-core/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ glam = "0.16.0"
2424
indexmap = "1.6.0"
2525
ahash = "0.7.0"
2626
once_cell = "1.7.2"
27+
serde = { version = "1", default_features = false, features = ["derive"], optional = true }
2728

2829
gdnative-impl-proc-macros = { path = "../impl/proc_macros", version = "=0.9.3" }
2930

gdnative-core/src/core_types/color.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::core_types::GodotString;
66
/// RGBA color with 32 bits floating point components.
77
#[repr(C)]
88
#[derive(Copy, Clone, Debug, PartialEq)]
9+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
910
pub struct Color {
1011
pub r: f32,
1112
pub g: f32,

gdnative-core/src/core_types/dictionary.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,82 @@ impl Clone for Dictionary {
612612
}
613613
}
614614

615+
#[cfg(feature = "serde")]
616+
pub(super) mod serde {
617+
use super::*;
618+
use ::serde::{
619+
de::{MapAccess, Visitor},
620+
ser::SerializeMap,
621+
Deserialize, Deserializer, Serialize, Serializer,
622+
};
623+
use std::fmt::Formatter;
624+
625+
impl Serialize for Dictionary {
626+
#[inline]
627+
fn serialize<S>(&self, ser: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
628+
where
629+
S: Serializer,
630+
{
631+
let mut ser = ser.serialize_map(Some(self.len() as usize))?;
632+
for (key, value) in self.iter() {
633+
ser.serialize_entry(&key, &value)?
634+
}
635+
ser.end()
636+
}
637+
}
638+
639+
pub(in super::super) struct DictionaryVisitor;
640+
641+
impl<'de> Visitor<'de> for DictionaryVisitor {
642+
type Value = Dictionary<Unique>;
643+
644+
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
645+
formatter.write_str("a Dictionary")
646+
}
647+
648+
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, <A as MapAccess<'de>>::Error>
649+
where
650+
A: MapAccess<'de>,
651+
{
652+
let dict = Dictionary::new();
653+
while let Some((key, value)) = map.next_entry::<Variant, Variant>()? {
654+
dict.insert(key, value)
655+
}
656+
Ok(dict)
657+
}
658+
}
659+
660+
impl<'de> Deserialize<'de> for Dictionary<Unique> {
661+
#[inline]
662+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
663+
where
664+
D: Deserializer<'de>,
665+
{
666+
deserializer.deserialize_map(DictionaryVisitor)
667+
}
668+
}
669+
670+
impl<'de> Deserialize<'de> for Dictionary<Shared> {
671+
#[inline]
672+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
673+
where
674+
D: Deserializer<'de>,
675+
{
676+
Dictionary::<Unique>::deserialize(deserializer).map(Dictionary::into_shared)
677+
}
678+
}
679+
680+
impl<'de> Deserialize<'de> for Dictionary<ThreadLocal> {
681+
#[inline]
682+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
683+
where
684+
D: Deserializer<'de>,
685+
{
686+
Dictionary::<Unique>::deserialize(deserializer).map(Dictionary::into_thread_local)
687+
}
688+
}
689+
}
690+
615691
godot_test!(test_dictionary {
616692
use std::collections::HashSet;
617693

gdnative-core/src/core_types/error.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::sys;
22

33
/// Error codes used in various Godot APIs.
44
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
5+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
56
#[repr(u32)]
67
pub enum GodotError {
78
Failed = sys::godot_error_GODOT_FAILED as u32,

gdnative-core/src/core_types/geom/aabb.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::core_types::Vector3;
33
/// Axis-aligned bounding box.
44
#[repr(C)]
55
#[derive(Copy, Clone, Debug, PartialEq)]
6+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
67
pub struct Aabb {
78
pub position: Vector3,
89
pub size: Vector3,

gdnative-core/src/core_types/geom/basis.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use core::ops::Mul;
44
/// A 3x3 matrix.
55
#[repr(C)]
66
#[derive(Copy, Clone, Debug, PartialEq)]
7+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
78
pub struct Basis {
89
pub elements: [Vector3; 3],
910
}

gdnative-core/src/core_types/geom/plane.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::core_types::{IsEqualApprox, Vector3};
33
/// Plane in hessian form.
44
#[repr(C)]
55
#[derive(Copy, Clone, Debug, PartialEq)]
6+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
67
pub struct Plane {
78
pub normal: Vector3,
89
pub d: f32,

gdnative-core/src/core_types/geom/transform.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::core_types::{Basis, Vector3};
33
/// 3D Transformation (3x4 matrix) Using basis + origin representation.
44
#[repr(C)]
55
#[derive(Copy, Clone, Debug, PartialEq)]
6+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
67
pub struct Transform {
78
/// The basis is a matrix containing 3 Vector3 as its columns: X axis, Y axis, and Z axis.
89
/// These vectors can be interpreted as the basis vectors of local coordinate system

gdnative-core/src/core_types/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ pub use rid::*;
4343
pub use string::*;
4444
pub use string_array::*;
4545
pub use transform2d::*;
46-
pub use typed_array::TypedArray;
46+
pub use typed_array::{Element, TypedArray};
4747
pub use variant::*;
4848
pub use variant_array::*;
4949
pub use vector2::*;

gdnative-core/src/core_types/node_path.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,3 +183,67 @@ impl Clone for NodePath {
183183
self.new_ref()
184184
}
185185
}
186+
187+
#[cfg(feature = "serde")]
188+
mod serde {
189+
use super::*;
190+
use ::serde::{
191+
de::{Error, Visitor},
192+
Deserialize, Deserializer, Serialize, Serializer,
193+
};
194+
use std::fmt::Formatter;
195+
196+
impl Serialize for NodePath {
197+
#[inline]
198+
fn serialize<S>(&self, ser: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
199+
where
200+
S: Serializer,
201+
{
202+
ser.serialize_newtype_struct("NodePath", &*self.to_string())
203+
}
204+
}
205+
206+
impl<'de> Deserialize<'de> for NodePath {
207+
#[inline]
208+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
209+
where
210+
D: Deserializer<'de>,
211+
{
212+
struct NodePathVisitor;
213+
214+
impl<'de> Visitor<'de> for NodePathVisitor {
215+
type Value = NodePath;
216+
217+
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
218+
formatter.write_str("a NodePath")
219+
}
220+
221+
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
222+
where
223+
E: Error,
224+
{
225+
Ok(NodePath::from_str(s))
226+
}
227+
228+
fn visit_string<E>(self, s: String) -> Result<Self::Value, E>
229+
where
230+
E: Error,
231+
{
232+
Ok(NodePath::from_str(&*s))
233+
}
234+
235+
fn visit_newtype_struct<D>(
236+
self,
237+
deserializer: D,
238+
) -> Result<Self::Value, <D as Deserializer<'de>>::Error>
239+
where
240+
D: Deserializer<'de>,
241+
{
242+
deserializer.deserialize_str(self)
243+
}
244+
}
245+
246+
deserializer.deserialize_newtype_struct("NodePath", NodePathVisitor)
247+
}
248+
}
249+
}

0 commit comments

Comments
 (0)