Skip to main content

extendable_assets/asset/serialize/
mod.rs

1mod backend;
2mod compression;
3mod data;
4pub use backend::*;
5pub use compression::*;
6pub use data::*;
7
8#[cfg(feature = "backend-json")]
9mod json_backend;
10#[cfg(feature = "backend-json")]
11pub use json_backend::*;
12
13#[cfg(feature = "backend-msgpack")]
14mod msgpack_backend;
15#[cfg(feature = "backend-msgpack")]
16pub use msgpack_backend::*;
17
18use serde::{Deserialize, Serialize};
19
20use crate::asset::AssetId;
21
22/// A serialized representation of an asset for storage or transmission.
23///
24/// This struct contains all the necessary information to reconstruct an asset,
25/// including its ID, type information, and the serialized data payload.
26/// The data is stored as raw bytes and uses serde_bytes for efficient
27/// serialization and deserialization.
28#[derive(Debug)]
29#[derive(Deserialize, Serialize)]
30pub struct SerializedAsset {
31    /// The unique identifier of the asset
32    #[serde(default)]
33    pub id: AssetId,
34    /// The name of the asset type used to determine how to deserialize the data
35    pub asset_type: String,
36    /// The serialized asset data, which may be compressed
37    pub data: SerializedData,
38}
39
40impl PartialEq for SerializedAsset {
41    /// Compares two SerializedAsset instances for equality.
42    ///
43    /// Two assets are considered equal if all their fields match exactly.
44    fn eq(&self, other: &Self) -> bool {
45        self.id == other.id && self.asset_type == other.asset_type && self.data == other.data
46    }
47}
48
49#[cfg(test)]
50mod test {
51    use super::*;
52    use rand::RngExt;
53    use serde_test::{Token, assert_tokens};
54    use std::sync::LazyLock;
55
56    /// Static test data with 'static lifetime required by Token::Bytes.
57    /// LazyLock provides thread-safe lazy initialization of random data.
58    static DATA: LazyLock<SerializedData> = LazyLock::new(|| {
59        let mut rng = rand::rng();
60        let mut data = vec![0u8; 128];
61        rng.fill(&mut data[..]);
62        SerializedData::Uncompressed(data)
63    });
64
65    /// Tests SerializedAsset serde implementation
66    #[test]
67    fn serialized_asset_serde() {
68        let mut rng = rand::rng();
69        // Generate a random asset ID for testing
70        let id: AssetId = rng.random();
71        let asset_type: String = "TestAsset".into();
72
73        let asset = SerializedAsset {
74            id,
75            asset_type: asset_type.clone(),
76            data: DATA.clone(),
77        };
78        let tokens = &[
79            Token::Struct {
80                name: "SerializedAsset",
81                len: 3,
82            },
83            Token::Str("id"),
84            Token::U64(asset.id.into()),
85            Token::Str("asset_type"),
86            Token::String("TestAsset"),
87            Token::Str("data"),
88            // Token::Bytes requires &'static [u8], provided by static DATA
89            Token::Bytes(DATA.data()),
90            Token::StructEnd,
91        ];
92        assert_tokens(&asset, tokens);
93    }
94}