Skip to main content

bevy_image/
serialized_image.rs

1use crate::{Image, ImageSampler};
2use bevy_asset::RenderAssetUsages;
3use core::fmt::Debug;
4use serde::{Deserialize, Serialize};
5use wgpu_types::{
6    TextureAspect, TextureDataOrder, TextureDescriptor, TextureFormat, TextureUsages,
7    TextureViewDescriptor, TextureViewDimension,
8};
9
10/// A version of [`Image`] suitable for serializing for short-term transfer.
11///
12/// [`Image`] does not implement [`Serialize`] / [`Deserialize`] because it is made with the renderer in mind.
13/// It is not a general-purpose image implementation, and its internals are subject to frequent change.
14/// As such, storing an [`Image`] on disk is highly discouraged.
15/// Use an existing image asset format such as `.png` instead!
16///
17/// But there are still some valid use cases for serializing an [`Image`], namely transferring images between processes.
18/// To support this, you can create a [`SerializedImage`] from an [`Image`] with [`SerializedImage::from_image`],
19/// and then deserialize it with [`SerializedImage::into_image`].
20///
21/// The caveats are:
22/// - The image representation is not valid across different versions of Bevy.
23/// - This conversion is lossy. The following information is not preserved:
24///   - texture descriptor and texture view descriptor labels
25///   - texture descriptor view formats
26#[derive(#[automatically_derived]
impl ::core::fmt::Debug for SerializedImage {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field5_finish(f,
            "SerializedImage", "data", &self.data, "data_order",
            &self.data_order, "texture_descriptor", &self.texture_descriptor,
            "sampler", &self.sampler, "texture_view_descriptor",
            &&self.texture_view_descriptor)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for SerializedImage {
    #[inline]
    fn clone(&self) -> SerializedImage {
        SerializedImage {
            data: ::core::clone::Clone::clone(&self.data),
            data_order: ::core::clone::Clone::clone(&self.data_order),
            texture_descriptor: ::core::clone::Clone::clone(&self.texture_descriptor),
            sampler: ::core::clone::Clone::clone(&self.sampler),
            texture_view_descriptor: ::core::clone::Clone::clone(&self.texture_view_descriptor),
        }
    }
}Clone, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for SerializedImage {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                let mut __serde_state =
                    _serde::Serializer::serialize_struct(__serializer,
                            "SerializedImage", false as usize + 1 + 1 + 1 + 1 + 1)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "data", &self.data)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "data_order", &self.data_order)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "texture_descriptor", &self.texture_descriptor)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "sampler", &self.sampler)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "texture_view_descriptor", &self.texture_view_descriptor)?;
                _serde::ser::SerializeStruct::end(__serde_state)
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for SerializedImage {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field {
                    __field0,
                    __field1,
                    __field2,
                    __field3,
                    __field4,
                    __ignore,
                }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "field identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private228::Ok(__Field::__field0),
                            1u64 => _serde::__private228::Ok(__Field::__field1),
                            2u64 => _serde::__private228::Ok(__Field::__field2),
                            3u64 => _serde::__private228::Ok(__Field::__field3),
                            4u64 => _serde::__private228::Ok(__Field::__field4),
                            _ => _serde::__private228::Ok(__Field::__ignore),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "data" => _serde::__private228::Ok(__Field::__field0),
                            "data_order" => _serde::__private228::Ok(__Field::__field1),
                            "texture_descriptor" =>
                                _serde::__private228::Ok(__Field::__field2),
                            "sampler" => _serde::__private228::Ok(__Field::__field3),
                            "texture_view_descriptor" =>
                                _serde::__private228::Ok(__Field::__field4),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"data" => _serde::__private228::Ok(__Field::__field0),
                            b"data_order" =>
                                _serde::__private228::Ok(__Field::__field1),
                            b"texture_descriptor" =>
                                _serde::__private228::Ok(__Field::__field2),
                            b"sampler" => _serde::__private228::Ok(__Field::__field3),
                            b"texture_view_descriptor" =>
                                _serde::__private228::Ok(__Field::__field4),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private228::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<SerializedImage>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = SerializedImage;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "struct SerializedImage")
                    }
                    #[inline]
                    fn visit_seq<__A>(self, mut __seq: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::SeqAccess<'de> {
                        let __field0 =
                            match _serde::de::SeqAccess::next_element::<Option<Vec<u8>>>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                &"struct SerializedImage with 5 elements")),
                            };
                        let __field1 =
                            match _serde::de::SeqAccess::next_element::<SerializedTextureDataOrder>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                &"struct SerializedImage with 5 elements")),
                            };
                        let __field2 =
                            match _serde::de::SeqAccess::next_element::<TextureDescriptor<(),
                                            ()>>(&mut __seq)? {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(2usize,
                                                &"struct SerializedImage with 5 elements")),
                            };
                        let __field3 =
                            match _serde::de::SeqAccess::next_element::<ImageSampler>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(3usize,
                                                &"struct SerializedImage with 5 elements")),
                            };
                        let __field4 =
                            match _serde::de::SeqAccess::next_element::<Option<SerializedTextureViewDescriptor>>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(4usize,
                                                &"struct SerializedImage with 5 elements")),
                            };
                        _serde::__private228::Ok(SerializedImage {
                                data: __field0,
                                data_order: __field1,
                                texture_descriptor: __field2,
                                sampler: __field3,
                                texture_view_descriptor: __field4,
                            })
                    }
                    #[inline]
                    fn visit_map<__A>(self, mut __map: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::MapAccess<'de> {
                        let mut __field0:
                                _serde::__private228::Option<Option<Vec<u8>>> =
                            _serde::__private228::None;
                        let mut __field1:
                                _serde::__private228::Option<SerializedTextureDataOrder> =
                            _serde::__private228::None;
                        let mut __field2:
                                _serde::__private228::Option<TextureDescriptor<(), ()>> =
                            _serde::__private228::None;
                        let mut __field3:
                                _serde::__private228::Option<ImageSampler> =
                            _serde::__private228::None;
                        let mut __field4:
                                _serde::__private228::Option<Option<SerializedTextureViewDescriptor>> =
                            _serde::__private228::None;
                        while let _serde::__private228::Some(__key) =
                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                            match __key {
                                __Field::__field0 => {
                                    if _serde::__private228::Option::is_some(&__field0) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("data"));
                                    }
                                    __field0 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<Option<Vec<u8>>>(&mut __map)?);
                                }
                                __Field::__field1 => {
                                    if _serde::__private228::Option::is_some(&__field1) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("data_order"));
                                    }
                                    __field1 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<SerializedTextureDataOrder>(&mut __map)?);
                                }
                                __Field::__field2 => {
                                    if _serde::__private228::Option::is_some(&__field2) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("texture_descriptor"));
                                    }
                                    __field2 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<TextureDescriptor<(),
                                                        ()>>(&mut __map)?);
                                }
                                __Field::__field3 => {
                                    if _serde::__private228::Option::is_some(&__field3) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("sampler"));
                                    }
                                    __field3 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<ImageSampler>(&mut __map)?);
                                }
                                __Field::__field4 => {
                                    if _serde::__private228::Option::is_some(&__field4) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("texture_view_descriptor"));
                                    }
                                    __field4 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<Option<SerializedTextureViewDescriptor>>(&mut __map)?);
                                }
                                _ => {
                                    let _ =
                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                }
                            }
                        }
                        let __field0 =
                            match __field0 {
                                _serde::__private228::Some(__field0) => __field0,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("data")?,
                            };
                        let __field1 =
                            match __field1 {
                                _serde::__private228::Some(__field1) => __field1,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("data_order")?,
                            };
                        let __field2 =
                            match __field2 {
                                _serde::__private228::Some(__field2) => __field2,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("texture_descriptor")?,
                            };
                        let __field3 =
                            match __field3 {
                                _serde::__private228::Some(__field3) => __field3,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("sampler")?,
                            };
                        let __field4 =
                            match __field4 {
                                _serde::__private228::Some(__field4) => __field4,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("texture_view_descriptor")?,
                            };
                        _serde::__private228::Ok(SerializedImage {
                                data: __field0,
                                data_order: __field1,
                                texture_descriptor: __field2,
                                sampler: __field3,
                                texture_view_descriptor: __field4,
                            })
                    }
                }
                #[doc(hidden)]
                const FIELDS: &'static [&'static str] =
                    &["data", "data_order", "texture_descriptor", "sampler",
                                "texture_view_descriptor"];
                _serde::Deserializer::deserialize_struct(__deserializer,
                    "SerializedImage", FIELDS,
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<SerializedImage>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };Deserialize)]
27pub struct SerializedImage {
28    data: Option<Vec<u8>>,
29    data_order: SerializedTextureDataOrder,
30    texture_descriptor: TextureDescriptor<(), ()>,
31    sampler: ImageSampler,
32    texture_view_descriptor: Option<SerializedTextureViewDescriptor>,
33}
34
35#[derive(#[automatically_derived]
impl ::core::fmt::Debug for SerializedTextureViewDescriptor {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        let names: &'static _ =
            &["format", "dimension", "usage", "aspect", "base_mip_level",
                        "mip_level_count", "base_array_layer", "array_layer_count"];
        let values: &[&dyn ::core::fmt::Debug] =
            &[&self.format, &self.dimension, &self.usage, &self.aspect,
                        &self.base_mip_level, &self.mip_level_count,
                        &self.base_array_layer, &&self.array_layer_count];
        ::core::fmt::Formatter::debug_struct_fields_finish(f,
            "SerializedTextureViewDescriptor", names, values)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for SerializedTextureViewDescriptor {
    #[inline]
    fn clone(&self) -> SerializedTextureViewDescriptor {
        SerializedTextureViewDescriptor {
            format: ::core::clone::Clone::clone(&self.format),
            dimension: ::core::clone::Clone::clone(&self.dimension),
            usage: ::core::clone::Clone::clone(&self.usage),
            aspect: ::core::clone::Clone::clone(&self.aspect),
            base_mip_level: ::core::clone::Clone::clone(&self.base_mip_level),
            mip_level_count: ::core::clone::Clone::clone(&self.mip_level_count),
            base_array_layer: ::core::clone::Clone::clone(&self.base_array_layer),
            array_layer_count: ::core::clone::Clone::clone(&self.array_layer_count),
        }
    }
}Clone, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for SerializedTextureViewDescriptor {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                let mut __serde_state =
                    _serde::Serializer::serialize_struct(__serializer,
                            "SerializedTextureViewDescriptor",
                            false as usize + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "format", &self.format)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "dimension", &self.dimension)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "usage", &self.usage)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "aspect", &self.aspect)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "base_mip_level", &self.base_mip_level)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "mip_level_count", &self.mip_level_count)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "base_array_layer", &self.base_array_layer)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "array_layer_count", &self.array_layer_count)?;
                _serde::ser::SerializeStruct::end(__serde_state)
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for SerializedTextureViewDescriptor
            {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field {
                    __field0,
                    __field1,
                    __field2,
                    __field3,
                    __field4,
                    __field5,
                    __field6,
                    __field7,
                    __ignore,
                }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "field identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private228::Ok(__Field::__field0),
                            1u64 => _serde::__private228::Ok(__Field::__field1),
                            2u64 => _serde::__private228::Ok(__Field::__field2),
                            3u64 => _serde::__private228::Ok(__Field::__field3),
                            4u64 => _serde::__private228::Ok(__Field::__field4),
                            5u64 => _serde::__private228::Ok(__Field::__field5),
                            6u64 => _serde::__private228::Ok(__Field::__field6),
                            7u64 => _serde::__private228::Ok(__Field::__field7),
                            _ => _serde::__private228::Ok(__Field::__ignore),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "format" => _serde::__private228::Ok(__Field::__field0),
                            "dimension" => _serde::__private228::Ok(__Field::__field1),
                            "usage" => _serde::__private228::Ok(__Field::__field2),
                            "aspect" => _serde::__private228::Ok(__Field::__field3),
                            "base_mip_level" =>
                                _serde::__private228::Ok(__Field::__field4),
                            "mip_level_count" =>
                                _serde::__private228::Ok(__Field::__field5),
                            "base_array_layer" =>
                                _serde::__private228::Ok(__Field::__field6),
                            "array_layer_count" =>
                                _serde::__private228::Ok(__Field::__field7),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"format" => _serde::__private228::Ok(__Field::__field0),
                            b"dimension" => _serde::__private228::Ok(__Field::__field1),
                            b"usage" => _serde::__private228::Ok(__Field::__field2),
                            b"aspect" => _serde::__private228::Ok(__Field::__field3),
                            b"base_mip_level" =>
                                _serde::__private228::Ok(__Field::__field4),
                            b"mip_level_count" =>
                                _serde::__private228::Ok(__Field::__field5),
                            b"base_array_layer" =>
                                _serde::__private228::Ok(__Field::__field6),
                            b"array_layer_count" =>
                                _serde::__private228::Ok(__Field::__field7),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private228::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<SerializedTextureViewDescriptor>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = SerializedTextureViewDescriptor;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "struct SerializedTextureViewDescriptor")
                    }
                    #[inline]
                    fn visit_seq<__A>(self, mut __seq: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::SeqAccess<'de> {
                        let __field0 =
                            match _serde::de::SeqAccess::next_element::<Option<TextureFormat>>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                &"struct SerializedTextureViewDescriptor with 8 elements")),
                            };
                        let __field1 =
                            match _serde::de::SeqAccess::next_element::<Option<TextureViewDimension>>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                &"struct SerializedTextureViewDescriptor with 8 elements")),
                            };
                        let __field2 =
                            match _serde::de::SeqAccess::next_element::<Option<TextureUsages>>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(2usize,
                                                &"struct SerializedTextureViewDescriptor with 8 elements")),
                            };
                        let __field3 =
                            match _serde::de::SeqAccess::next_element::<TextureAspect>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(3usize,
                                                &"struct SerializedTextureViewDescriptor with 8 elements")),
                            };
                        let __field4 =
                            match _serde::de::SeqAccess::next_element::<u32>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(4usize,
                                                &"struct SerializedTextureViewDescriptor with 8 elements")),
                            };
                        let __field5 =
                            match _serde::de::SeqAccess::next_element::<Option<u32>>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(5usize,
                                                &"struct SerializedTextureViewDescriptor with 8 elements")),
                            };
                        let __field6 =
                            match _serde::de::SeqAccess::next_element::<u32>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(6usize,
                                                &"struct SerializedTextureViewDescriptor with 8 elements")),
                            };
                        let __field7 =
                            match _serde::de::SeqAccess::next_element::<Option<u32>>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(7usize,
                                                &"struct SerializedTextureViewDescriptor with 8 elements")),
                            };
                        _serde::__private228::Ok(SerializedTextureViewDescriptor {
                                format: __field0,
                                dimension: __field1,
                                usage: __field2,
                                aspect: __field3,
                                base_mip_level: __field4,
                                mip_level_count: __field5,
                                base_array_layer: __field6,
                                array_layer_count: __field7,
                            })
                    }
                    #[inline]
                    fn visit_map<__A>(self, mut __map: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::MapAccess<'de> {
                        let mut __field0:
                                _serde::__private228::Option<Option<TextureFormat>> =
                            _serde::__private228::None;
                        let mut __field1:
                                _serde::__private228::Option<Option<TextureViewDimension>> =
                            _serde::__private228::None;
                        let mut __field2:
                                _serde::__private228::Option<Option<TextureUsages>> =
                            _serde::__private228::None;
                        let mut __field3:
                                _serde::__private228::Option<TextureAspect> =
                            _serde::__private228::None;
                        let mut __field4: _serde::__private228::Option<u32> =
                            _serde::__private228::None;
                        let mut __field5:
                                _serde::__private228::Option<Option<u32>> =
                            _serde::__private228::None;
                        let mut __field6: _serde::__private228::Option<u32> =
                            _serde::__private228::None;
                        let mut __field7:
                                _serde::__private228::Option<Option<u32>> =
                            _serde::__private228::None;
                        while let _serde::__private228::Some(__key) =
                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                            match __key {
                                __Field::__field0 => {
                                    if _serde::__private228::Option::is_some(&__field0) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("format"));
                                    }
                                    __field0 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<Option<TextureFormat>>(&mut __map)?);
                                }
                                __Field::__field1 => {
                                    if _serde::__private228::Option::is_some(&__field1) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("dimension"));
                                    }
                                    __field1 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<Option<TextureViewDimension>>(&mut __map)?);
                                }
                                __Field::__field2 => {
                                    if _serde::__private228::Option::is_some(&__field2) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("usage"));
                                    }
                                    __field2 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<Option<TextureUsages>>(&mut __map)?);
                                }
                                __Field::__field3 => {
                                    if _serde::__private228::Option::is_some(&__field3) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("aspect"));
                                    }
                                    __field3 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<TextureAspect>(&mut __map)?);
                                }
                                __Field::__field4 => {
                                    if _serde::__private228::Option::is_some(&__field4) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("base_mip_level"));
                                    }
                                    __field4 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<u32>(&mut __map)?);
                                }
                                __Field::__field5 => {
                                    if _serde::__private228::Option::is_some(&__field5) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("mip_level_count"));
                                    }
                                    __field5 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<Option<u32>>(&mut __map)?);
                                }
                                __Field::__field6 => {
                                    if _serde::__private228::Option::is_some(&__field6) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("base_array_layer"));
                                    }
                                    __field6 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<u32>(&mut __map)?);
                                }
                                __Field::__field7 => {
                                    if _serde::__private228::Option::is_some(&__field7) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("array_layer_count"));
                                    }
                                    __field7 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<Option<u32>>(&mut __map)?);
                                }
                                _ => {
                                    let _ =
                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                }
                            }
                        }
                        let __field0 =
                            match __field0 {
                                _serde::__private228::Some(__field0) => __field0,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("format")?,
                            };
                        let __field1 =
                            match __field1 {
                                _serde::__private228::Some(__field1) => __field1,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("dimension")?,
                            };
                        let __field2 =
                            match __field2 {
                                _serde::__private228::Some(__field2) => __field2,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("usage")?,
                            };
                        let __field3 =
                            match __field3 {
                                _serde::__private228::Some(__field3) => __field3,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("aspect")?,
                            };
                        let __field4 =
                            match __field4 {
                                _serde::__private228::Some(__field4) => __field4,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("base_mip_level")?,
                            };
                        let __field5 =
                            match __field5 {
                                _serde::__private228::Some(__field5) => __field5,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("mip_level_count")?,
                            };
                        let __field6 =
                            match __field6 {
                                _serde::__private228::Some(__field6) => __field6,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("base_array_layer")?,
                            };
                        let __field7 =
                            match __field7 {
                                _serde::__private228::Some(__field7) => __field7,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("array_layer_count")?,
                            };
                        _serde::__private228::Ok(SerializedTextureViewDescriptor {
                                format: __field0,
                                dimension: __field1,
                                usage: __field2,
                                aspect: __field3,
                                base_mip_level: __field4,
                                mip_level_count: __field5,
                                base_array_layer: __field6,
                                array_layer_count: __field7,
                            })
                    }
                }
                #[doc(hidden)]
                const FIELDS: &'static [&'static str] =
                    &["format", "dimension", "usage", "aspect",
                                "base_mip_level", "mip_level_count", "base_array_layer",
                                "array_layer_count"];
                _serde::Deserializer::deserialize_struct(__deserializer,
                    "SerializedTextureViewDescriptor", FIELDS,
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<SerializedTextureViewDescriptor>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };Deserialize)]
36struct SerializedTextureViewDescriptor {
37    format: Option<TextureFormat>,
38    dimension: Option<TextureViewDimension>,
39    usage: Option<TextureUsages>,
40    aspect: TextureAspect,
41    base_mip_level: u32,
42    mip_level_count: Option<u32>,
43    base_array_layer: u32,
44    array_layer_count: Option<u32>,
45}
46
47impl SerializedTextureViewDescriptor {
48    fn from_texture_view_descriptor(
49        descriptor: TextureViewDescriptor<Option<&'static str>>,
50    ) -> Self {
51        Self {
52            format: descriptor.format,
53            dimension: descriptor.dimension,
54            usage: descriptor.usage,
55            aspect: descriptor.aspect,
56            base_mip_level: descriptor.base_mip_level,
57            mip_level_count: descriptor.mip_level_count,
58            base_array_layer: descriptor.base_array_layer,
59            array_layer_count: descriptor.array_layer_count,
60        }
61    }
62
63    fn into_texture_view_descriptor(self) -> TextureViewDescriptor<Option<&'static str>> {
64        TextureViewDescriptor {
65            // Not used for asset-based images other than debugging
66            label: None,
67            format: self.format,
68            dimension: self.dimension,
69            usage: self.usage,
70            aspect: self.aspect,
71            base_mip_level: self.base_mip_level,
72            mip_level_count: self.mip_level_count,
73            base_array_layer: self.base_array_layer,
74            array_layer_count: self.array_layer_count,
75        }
76    }
77}
78
79#[derive(#[automatically_derived]
impl ::core::fmt::Debug for SerializedTextureDataOrder {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                SerializedTextureDataOrder::LayerMajor => "LayerMajor",
                SerializedTextureDataOrder::MipMajor => "MipMajor",
            })
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for SerializedTextureDataOrder {
    #[inline]
    fn clone(&self) -> SerializedTextureDataOrder {
        match self {
            SerializedTextureDataOrder::LayerMajor =>
                SerializedTextureDataOrder::LayerMajor,
            SerializedTextureDataOrder::MipMajor =>
                SerializedTextureDataOrder::MipMajor,
        }
    }
}Clone, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for SerializedTextureDataOrder {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                match *self {
                    SerializedTextureDataOrder::LayerMajor =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "SerializedTextureDataOrder", 0u32, "LayerMajor"),
                    SerializedTextureDataOrder::MipMajor =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "SerializedTextureDataOrder", 1u32, "MipMajor"),
                }
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for SerializedTextureDataOrder {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field { __field0, __field1, }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "variant identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private228::Ok(__Field::__field0),
                            1u64 => _serde::__private228::Ok(__Field::__field1),
                            _ =>
                                _serde::__private228::Err(_serde::de::Error::invalid_value(_serde::de::Unexpected::Unsigned(__value),
                                        &"variant index 0 <= i < 2")),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "LayerMajor" => _serde::__private228::Ok(__Field::__field0),
                            "MipMajor" => _serde::__private228::Ok(__Field::__field1),
                            _ => {
                                _serde::__private228::Err(_serde::de::Error::unknown_variant(__value,
                                        VARIANTS))
                            }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"LayerMajor" =>
                                _serde::__private228::Ok(__Field::__field0),
                            b"MipMajor" => _serde::__private228::Ok(__Field::__field1),
                            _ => {
                                let __value =
                                    &_serde::__private228::from_utf8_lossy(__value);
                                _serde::__private228::Err(_serde::de::Error::unknown_variant(__value,
                                        VARIANTS))
                            }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private228::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<SerializedTextureDataOrder>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = SerializedTextureDataOrder;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "enum SerializedTextureDataOrder")
                    }
                    fn visit_enum<__A>(self, __data: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::EnumAccess<'de> {
                        match _serde::de::EnumAccess::variant(__data)? {
                            (__Field::__field0, __variant) => {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private228::Ok(SerializedTextureDataOrder::LayerMajor)
                            }
                            (__Field::__field1, __variant) => {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private228::Ok(SerializedTextureDataOrder::MipMajor)
                            }
                        }
                    }
                }
                #[doc(hidden)]
                const VARIANTS: &'static [&'static str] =
                    &["LayerMajor", "MipMajor"];
                _serde::Deserializer::deserialize_enum(__deserializer,
                    "SerializedTextureDataOrder", VARIANTS,
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<SerializedTextureDataOrder>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };Deserialize)]
80enum SerializedTextureDataOrder {
81    LayerMajor,
82    MipMajor,
83}
84
85impl SerializedTextureDataOrder {
86    fn from_texture_data_order(order: TextureDataOrder) -> Self {
87        match order {
88            TextureDataOrder::LayerMajor => SerializedTextureDataOrder::LayerMajor,
89            TextureDataOrder::MipMajor => SerializedTextureDataOrder::MipMajor,
90        }
91    }
92
93    fn into_texture_data_order(self) -> TextureDataOrder {
94        match self {
95            SerializedTextureDataOrder::LayerMajor => TextureDataOrder::LayerMajor,
96            SerializedTextureDataOrder::MipMajor => TextureDataOrder::MipMajor,
97        }
98    }
99}
100
101impl SerializedImage {
102    /// Creates a new [`SerializedImage`] from an [`Image`].
103    pub fn from_image(image: Image) -> Self {
104        Self {
105            data: image.data,
106            data_order: SerializedTextureDataOrder::from_texture_data_order(image.data_order),
107            texture_descriptor: TextureDescriptor {
108                label: (),
109                size: image.texture_descriptor.size,
110                mip_level_count: image.texture_descriptor.mip_level_count,
111                sample_count: image.texture_descriptor.sample_count,
112                dimension: image.texture_descriptor.dimension,
113                format: image.texture_descriptor.format,
114                usage: image.texture_descriptor.usage,
115                view_formats: (),
116            },
117            sampler: image.sampler,
118            texture_view_descriptor: image.texture_view_descriptor.map(|descriptor| {
119                SerializedTextureViewDescriptor::from_texture_view_descriptor(descriptor)
120            }),
121        }
122    }
123
124    /// Create an [`Image`] from a [`SerializedImage`].
125    pub fn into_image(self) -> Image {
126        Image {
127            data: self.data,
128            data_order: self.data_order.into_texture_data_order(),
129            texture_descriptor: TextureDescriptor {
130                // Not used for asset-based images other than debugging
131                label: None,
132                size: self.texture_descriptor.size,
133                mip_level_count: self.texture_descriptor.mip_level_count,
134                sample_count: self.texture_descriptor.sample_count,
135                dimension: self.texture_descriptor.dimension,
136                format: self.texture_descriptor.format,
137                usage: self.texture_descriptor.usage,
138                // Not used for asset-based images
139                view_formats: &[],
140            },
141            sampler: self.sampler,
142            texture_view_descriptor: self
143                .texture_view_descriptor
144                .map(SerializedTextureViewDescriptor::into_texture_view_descriptor),
145            asset_usage: RenderAssetUsages::RENDER_WORLD,
146            copy_on_resize: false,
147        }
148    }
149}
150
151#[cfg(test)]
152mod tests {
153    use wgpu_types::{Extent3d, TextureDimension};
154
155    use super::*;
156
157    #[test]
158    fn serialize_deserialize_image() {
159        let image = Image::new(
160            Extent3d {
161                width: 3,
162                height: 1,
163                depth_or_array_layers: 1,
164            },
165            TextureDimension::D2,
166            vec![255, 0, 0, 255, 0, 255, 0, 255, 0, 0, 255, 255],
167            TextureFormat::Rgba8UnormSrgb,
168            RenderAssetUsages::RENDER_WORLD,
169        );
170
171        let serialized_image = SerializedImage::from_image(image.clone());
172        let serialized_string = serde_json::to_string(&serialized_image).unwrap();
173        let serialized_image_from_string: SerializedImage =
174            serde_json::from_str(&serialized_string).unwrap();
175        let deserialized_image = serialized_image_from_string.into_image();
176        assert_eq!(image, deserialized_image);
177    }
178}