havok_serde/ser/
mod.rs

1// SPDX-License-Identifier: Apache-2.0 OR MIT
2//
3// The following code was written by modifying serde ver. 1.0.202.
4// See: https://github.com/serde-rs/serde/commit/58b3af4c2915c3ae789778a11f3b7a468c1cec17
5//
6// And serde holds the same license as Rust. https://github.com/rust-lang/rust/pull/43498
7//
8// The default implementation does not fully express Havok's special XML format.
9//
10// # Modification details
11// - Rust std types -> Havok Types
12// - Changed serde method to Havok XML& binary data signatures, which are easier to modify.
13//! Serialization
14
15use crate::lib::*;
16
17mod impls;
18
19use havok_types::{
20    CString, Matrix3, Matrix4, Pointer, QsTransform, Quaternion, Rotation, Signature, StringPtr,
21    Transform, Ulong, Vector4, f16, variant::Variant,
22};
23
24#[cfg(feature = "std")]
25#[doc(no_inline)]
26pub use std::error::Error as StdError;
27
28////////////////////////////////////////////////////////////////////////////////
29
30macro_rules! declare_error_trait {
31    (Error: Sized $(+ $($super_trait:ident)::+)*) => {
32        /// Trait used by `Serialize` implementations to generically construct
33        /// errors belonging to the `Serializer` against which they are
34        /// currently running.
35        pub trait Error: Sized $(+ $($super_trait)::+)* {
36            /// Used when a [`Serialize`] implementation encounters any error
37            /// while serializing a type.
38            ///
39            /// The message should not be capitalized and should not end with a
40            /// period.
41            ///
42            /// For example, a filesystem [`Path`] may refuse to serialize
43            /// itself if it contains invalid UTF-8 data.
44            ///
45            /// [`Path`]: https://doc.rust-lang.org/std/path/struct.Path.html
46            /// [`Serialize`]: ../trait.Serialize.html
47            fn custom<T>(msg: T) -> Self
48            where
49                T: Display;
50        }
51    }
52}
53
54#[cfg(feature = "std")]
55declare_error_trait!(Error: Sized + StdError);
56
57#[cfg(not(feature = "std"))]
58declare_error_trait!(Error: Sized + Debug + Display);
59
60////////////////////////////////////////////////////////////////////////////////
61
62/// A **data structure** that can be serialized into any data format supported
63/// by Serde.
64///
65/// Serde provides `Serialize` implementations for all C++ Havok types.
66///
67/// Additionally, Serde provides a procedural macro called [`havok_serde_derive`] to
68/// automatically generate `Serialize` implementations for structs and enums in
69/// your program. See the [derive section of the manual] for how to use this.
70///
71/// In rare cases it may be necessary to implement `Serialize` manually for some
72/// type in your program. See the [Implementing `Serialize`] section of the
73/// manual for more about this.
74///
75/// # Support types
76///
77/// # Unsupported types
78/// There're never used in the Havok classes.(ver. hk2010)
79/// - `Zero`, `FunctionPointer`, `InplaceArray`, `HomogeneousArray`, `RelArray`, `Max`
80pub trait Serialize {
81    /// Serialize this value into the given Serde serializer.
82    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>;
83}
84
85////////////////////////////////////////////////////////////////////////////////
86
87/// A **data format** that can serialize any data structure supported by Serde.
88///
89/// The role of this trait is to define the serialization half of the [Serde
90/// data model], which is a way to categorize every Rust data structure into one
91/// of 29 possible types. Each method of the `Serializer` trait corresponds to
92/// one of the types of the data model.
93///
94/// Implementations of `Serialize` map themselves into this data model by
95/// invoking exactly one of the `Serializer` methods.
96pub trait Serializer {
97    /// The output type produced by this `Serializer` during successful
98    /// serialization. Most serializers that produce text or binary output
99    /// should set `Ok = ()` and serialize into an [`io::Write`] or buffer
100    /// contained within the `Serializer` instance. Serializers that build
101    /// in-memory data structures may be simplified by using `Ok` to propagate
102    /// the data structure around.
103    ///
104    /// [`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
105    type Ok;
106
107    /// The error type when some error occurs during serialization.
108    type Error: Error;
109
110    /// Type returned from [`serialize_seq`] for serializing the content of the
111    /// sequence.
112    ///
113    /// [`serialize_seq`]: #tymethod.serialize_seq
114    type SerializeSeq: SerializeSeq<Ok = Self::Ok, Error = Self::Error>;
115
116    /// [`serialize_struct`]: #tymethod.serialize_struct
117    type SerializeStruct: SerializeStruct<Ok = Self::Ok, Error = Self::Error>;
118
119    /// Type returned from [`serialize_enum_flags`] for serializing the
120    /// content of the struct variant.
121    ///
122    /// [`serialize_enum_flags`]: #tymethod.serialize_flags
123    type SerializeFlags: SerializeFlags<Ok = Self::Ok, Error = Self::Error>;
124
125    /// Serialize a `Void` value.
126    ///
127    /// No type information.
128    ///
129    /// This is often used to fill in generics elements with types for which generics are not used.
130    ///
131    /// - `hkArray<hkBool>` -> `vtype`: `TYPE_ARRAY`, `vsubtype`: `TYPE_BOOL`
132    /// - `hkBool -> `vtype`: `TYPE_BOOL`, `vsubtype`: `TYPE_VOID`
133    /// - There is also a pattern `hkArray<void>`. The type information is unknown, but this member always contains the `SERIALIZE_IGNORED` flag and can be skipped.
134    fn serialize_void(self, v: ()) -> Result<Self::Ok, Self::Error>;
135
136    /// Serialize a `bool` value.
137    fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error>;
138
139    /// Serialize an `char` value.
140    fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error>;
141
142    /// Serialize an `i8` value.
143    ///
144    /// If the format does not differentiate between `i8` and `i64`, a
145    /// reasonable implementation would be to cast the value to `i64` and
146    /// forward to `serialize_i64`.
147    fn serialize_int8(self, v: i8) -> Result<Self::Ok, Self::Error>;
148
149    /// Serialize an `u8` value.
150    fn serialize_uint8(self, v: u8) -> Result<Self::Ok, Self::Error>;
151
152    /// Serialize an `i16` value.
153    fn serialize_int16(self, v: i16) -> Result<Self::Ok, Self::Error>;
154
155    /// Serialize an `u16` value.
156    fn serialize_uint16(self, v: u16) -> Result<Self::Ok, Self::Error>;
157
158    /// Serialize an `i32` value.
159    fn serialize_int32(self, v: i32) -> Result<Self::Ok, Self::Error>;
160
161    /// Serialize an `u32` value.
162    fn serialize_uint32(self, v: u32) -> Result<Self::Ok, Self::Error>;
163
164    /// Serialize an `u64` value.
165    fn serialize_int64(self, v: i64) -> Result<Self::Ok, Self::Error>;
166
167    /// Serialize an `i64` value.
168    fn serialize_uint64(self, v: u64) -> Result<Self::Ok, Self::Error>;
169
170    /// Serialize an `f32` value.
171    fn serialize_real(self, v: f32) -> Result<Self::Ok, Self::Error>;
172
173    /// Serialize an `Vector4` value.
174    fn serialize_vector4(self, v: &Vector4) -> Result<Self::Ok, Self::Error>;
175
176    /// Serialize an `Quaternion` value.
177    fn serialize_quaternion(self, v: &Quaternion) -> Result<Self::Ok, Self::Error>;
178
179    /// Serialize an `Matrix3` value.
180    fn serialize_matrix3(self, v: &Matrix3) -> Result<Self::Ok, Self::Error>;
181
182    /// Serialize an `Rotation` value.
183    fn serialize_rotation(self, v: &Rotation) -> Result<Self::Ok, Self::Error>;
184
185    /// Serialize an `QsTransform` value.
186    fn serialize_qstransform(self, v: &QsTransform) -> Result<Self::Ok, Self::Error>;
187
188    /// Serialize an `Matrix4` value.
189    fn serialize_matrix4(self, v: &Matrix4) -> Result<Self::Ok, Self::Error>;
190
191    /// Serialize an `Transform` value.
192    fn serialize_transform(self, v: &Transform) -> Result<Self::Ok, Self::Error>;
193
194    /// Serialize an `Pointer` value.
195    fn serialize_pointer(self, v: Pointer) -> Result<Self::Ok, Self::Error>;
196
197    /// Serialize an `Array` value.
198    fn serialize_array(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error>;
199
200    /// Serialize an `Struct` value.
201    ///
202    /// sizes: C++ class size (x86, x86_64)
203    fn serialize_struct(
204        self,
205        name: &'static str,
206        class_meta: Option<(Pointer, Signature)>,
207        sizes: (u64, u64),
208    ) -> Result<Self::SerializeStruct, Self::Error>;
209
210    /// Serialize an `Variant` value.
211    ///
212    /// # Note
213    /// Never used(In the 2010 Havok classes)
214    ///
215    /// `hkVariant` is a structure with two pointers, but its identity is unknown,
216    /// so u128(`[u64; 2]`) of binary data is used as an argument instead. (If it is 32bit, you would need to cast it to u64(`[u32;2]`).)
217    fn serialize_variant(self, v: &Variant) -> Result<Self::Ok, Self::Error>;
218
219    /// Serialize an `CString` value.
220    fn serialize_cstring(self, v: &CString) -> Result<Self::Ok, Self::Error>;
221
222    /// Serialize an `ULong`(pointer size(u32 or u64)) value.
223    fn serialize_ulong(self, v: Ulong) -> Result<Self::Ok, Self::Error>;
224
225    /// Serialize an `enum` or `Flags` value.
226    fn serialize_enum_flags(self) -> Result<Self::SerializeFlags, Self::Error>;
227
228    /// Serialize an `Half`(`f16`) value.
229    fn serialize_half(self, v: f16) -> Result<Self::Ok, Self::Error>;
230
231    /// Serialize an `StringPtr` value.
232    fn serialize_stringptr(self, v: &StringPtr) -> Result<Self::Ok, Self::Error>;
233}
234
235/// Returned from `Serializer::serialize_array`.
236pub trait SerializeSeq {
237    /// Must match the `Ok` type of our `Serializer`.
238    type Ok;
239
240    /// Must match the `Error` type of our `Serializer`.
241    type Error: Error;
242
243    /// Serialize a primitive sequence element.
244    /// (e.g. `char`, `bool` `u8`..`u64`, `i8`..`i64`, `f32`, `Pointer`)
245    ///
246    /// # Note
247    /// index must be 0 based.
248    fn serialize_primitive_element<T>(
249        &mut self,
250        value: &T,
251        index: usize,
252        len: usize,
253    ) -> Result<(), Self::Error>
254    where
255        T: ?Sized + Serialize;
256
257    /// Serialize a Havok Class sequence element.(e.g. `T: impl HavokClass`)
258    fn serialize_class_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
259    where
260        T: ?Sized + Serialize + crate::HavokClass;
261
262    /// Serialize a math sequence element.(e.g. `Matrix3`)
263    fn serialize_math_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
264    where
265        T: ?Sized + Serialize;
266
267    // # Reason for existence of `cstring` & `stringptr` methods.
268    // - The work on XML is different from bytes and could not be abstracted.
269    // - Creating a combined type of `CString` and `StringPtr` would require cloning in array processing.
270
271    /// Serialize a cstring sequence element.
272    fn serialize_cstring_element(&mut self, value: &CString) -> Result<(), Self::Error>;
273
274    /// Serialize a stringptr sequence element.
275    fn serialize_stringptr_element(&mut self, value: &StringPtr) -> Result<(), Self::Error>;
276
277    /// Finish serializing a sequence.
278    fn end(self) -> Result<Self::Ok, Self::Error>;
279}
280
281/// Used for writing binary data in Array. (To write after the pointer type data)
282/// - `array_size` = `size of the pointer type` * `array len`
283#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
284pub enum TypeSize {
285    /// C++ Class size
286    Struct {
287        /// x86 class size
288        size_x86: u64,
289        /// x86_64 class size
290        size_x86_64: u64,
291    },
292    /// ptr size
293    String,
294    /// No size calculation is required for NonPtr.
295    /// This is an option for types other than `StringPtr`, `CString`, and `Struct`.
296    NonPtr,
297}
298
299/// Returned from `Serializer::serialize_struct`.
300///
301/// The [example data format] presented on the website demonstrates an
302/// implementation of `SerializeStruct` for a basic JSON data format.
303///
304/// [example data format]: https://serde.rs/data-format.html
305///
306/// # Flatten is unsupportable
307/// If the parent is a ptr type, the process of simply writing the parent cannot be used as it is because the data writing of the ptr destination is waiting after the writing of all fields.
308/// Therefore, `serialize` of the parent struct cannot be reused.
309pub trait SerializeStruct {
310    /// Must match the `Ok` type of our `Serializer`.
311    type Ok;
312
313    /// Must match the `Error` type of our `Serializer`.
314    type Error: Error;
315
316    /// Serialize a struct field.
317    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
318    where
319        T: ?Sized + Serialize;
320
321    /// Process for fields with `SERIALIZE_IGNORED` flag.
322    /// -   XML: Replaced by a comment and the actual data is not displayed.
323    /// - Bytes: the data itself is read/written
324    ///
325    /// The default implementation does nothing.
326    #[inline]
327    fn skip_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
328    where
329        T: ?Sized + Serialize,
330    {
331        let _ = key;
332        let _ = value;
333        Ok(())
334    }
335
336    /// Processing for padding to serialize binary data
337    ///
338    /// The default implementation does nothing.
339    #[inline]
340    fn pad_field<T>(&mut self, x86_pads: &T, x64_pads: &T) -> Result<(), Self::Error>
341    where
342        T: ?Sized + AsRef<[u8]>,
343    {
344        let _ = x86_pads;
345        let _ = x64_pads;
346        Ok(())
347    }
348
349    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
350    // Fixed Array
351
352    /// Serialize a struct field for fixed array.
353    /// -   XML: add `numelements` attribute to `hkparam` and write array contents.(same as `hkArray`)
354    /// - Bytes: write each bytes.
355    fn serialize_fixed_array_field<V, T>(
356        &mut self,
357        key: &'static str,
358        value: V,
359        size: TypeSize,
360    ) -> Result<(), Self::Error>
361    where
362        V: AsRef<[T]> + Serialize,
363        T: Serialize;
364
365    /// Process for fields with `SERIALIZE_IGNORED` flag.
366    ///
367    /// The default implementation same as `skip_field`
368    #[inline]
369    fn skip_fixed_array_field<V, T>(
370        &mut self,
371        key: &'static str,
372        value: V,
373        size: TypeSize,
374    ) -> Result<(), Self::Error>
375    where
376        V: AsRef<[T]> + Serialize,
377        T: Serialize,
378    {
379        let _ = size;
380        self.skip_field(key, &value)
381    }
382
383    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
384    // Array
385
386    /// Serialize a struct field for array.
387    /// -   XML: add `numelements` attribute to `hkparam` and write vec contents.
388    /// - Bytes: Alloc meta(ptr size + size + capAndFlags) bytes. (x86: 12, x64: 16) & Serialize pointed data.
389    #[inline]
390    fn serialize_array_field<V, T>(
391        &mut self,
392        key: &'static str,
393        value: V,
394        size: TypeSize,
395    ) -> Result<(), Self::Error>
396    where
397        V: AsRef<[T]> + Serialize,
398        T: Serialize,
399    {
400        let _ = (key, value, size);
401        Ok(())
402    }
403
404    /// Process for fields with `SERIALIZE_IGNORED` flag.
405    ///
406    /// The default implementation same as `skip_field`
407    #[inline]
408    fn skip_array_field<V, T>(
409        &mut self,
410        key: &'static str,
411        value: V,
412        size: TypeSize,
413    ) -> Result<(), Self::Error>
414    where
415        V: AsRef<[T]> + Serialize,
416        T: Serialize,
417    {
418        let _ = size;
419        self.skip_field(key, &value)
420    }
421
422    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
423
424    /// Finish serializing a struct.
425    fn end(self) -> Result<Self::Ok, Self::Error>;
426}
427
428/// Returned from `Serializer::serialize_enum_flags`.
429pub trait SerializeFlags {
430    /// Must match the `Ok` type of our `Serializer`.
431    type Ok;
432
433    /// Must match the `Error` type of our `Serializer`.
434    type Error: Error;
435
436    /// Serialization process when the flag is 0bits.(Only used by XML serializer.)
437    ///
438    /// The default implementation does nothing.
439    #[inline]
440    fn serialize_empty_bit(&mut self) -> Result<(), Self::Error> {
441        Ok(())
442    }
443
444    /// Serialize a enum or bit field.(Only used by XML serializer.)
445    fn serialize_field<T>(&mut self, key: &str, value: &T) -> Result<(), Self::Error>
446    where
447        T: ?Sized + Serialize;
448
449    /// Serialize all bits of a flag.(Only used by binary serializer.)
450    ///
451    /// The default implementation does nothing.
452    #[inline]
453    fn serialize_bits<T>(&mut self, value: &T) -> Result<(), Self::Error>
454    where
455        T: ?Sized + Serialize,
456    {
457        let _ = value;
458        Ok(())
459    }
460
461    /// Finish serializing flags.
462    fn end(self) -> Result<Self::Ok, Self::Error>;
463}