Skip to main content

extendable_assets/asset/serialize/
data.rs

1use crate::asset::serialize::CompressionMode;
2
3/// Represents serialized asset data that can be either compressed or uncompressed.
4///
5/// This enum uses serde's untagged serialization, meaning the variant is determined
6/// by the structure of the data rather than an explicit tag field.
7#[derive(Debug, Clone, PartialOrd, PartialEq)]
8#[derive(serde::Deserialize, serde::Serialize)]
9#[serde(untagged)]
10pub enum SerializedData {
11    /// Compressed data variant containing compression mode and compressed bytes
12    Compressed(
13        /// The compression algorithm used to compress the data
14        CompressionMode,
15        /// The compressed data as a byte vector, serialized efficiently as bytes
16        #[serde(with = "serde_bytes")]
17        Vec<u8>,
18    ),
19    /// Uncompressed data variant containing raw bytes
20    Uncompressed(
21        /// The raw uncompressed data as a byte vector, serialized efficiently as bytes
22        #[serde(with = "serde_bytes")]
23        Vec<u8>,
24    ),
25}
26
27impl SerializedData {
28    /// Returns the compression mode if the data is compressed, or None if uncompressed.
29    ///
30    /// This method allows checking whether the serialized data uses compression
31    /// and which compression algorithm was applied.
32    pub fn compression_mode(&self) -> Option<CompressionMode> {
33        match self {
34            SerializedData::Compressed(mode, _) => Some(*mode),
35            SerializedData::Uncompressed(_) => None,
36        }
37    }
38
39    /// Returns a reference to the underlying data bytes.
40    ///
41    /// For compressed data, this returns the compressed bytes.
42    /// For uncompressed data, this returns the raw bytes.
43    pub fn data(&self) -> &[u8] {
44        match self {
45            SerializedData::Compressed(_, data) => data,
46            SerializedData::Uncompressed(data) => data,
47        }
48    }
49}
50
51#[cfg(test)]
52mod test {
53    use super::*;
54    use rand::prelude::*;
55    use serde_json::json;
56
57    /// Tests that compressed data serializes as a tuple with compression mode and data
58    #[test]
59    fn compressed_enum_repr() {
60        // Generate random test data
61        let mut bytes = vec![0u8; 128];
62        rand::rng().fill(&mut bytes[..]);
63
64        // Create compressed data variant
65        let data = SerializedData::Compressed(CompressionMode::Zlib, bytes.clone());
66        // Expected JSON format: [compression_mode, data]
67        let expected = json!([CompressionMode::Zlib, bytes]);
68        let serialized = serde_json::to_value(data).unwrap();
69        assert_eq!(expected, serialized);
70    }
71
72    /// Tests that uncompressed data serializes as just the raw bytes
73    #[test]
74    fn uncompressed_enum_repr() {
75        // Generate random test data
76        let mut bytes = vec![0u8; 128];
77        rand::rng().fill(&mut bytes[..]);
78
79        // Create uncompressed data variant
80        let data = SerializedData::Uncompressed(bytes.clone());
81        // Expected JSON format: just the bytes array
82        let expected = json!(bytes);
83        let serialized = serde_json::to_value(data).unwrap();
84        assert_eq!(expected, serialized);
85    }
86}