Skip to main content

bevy_utils/
memory_size.rs

1//! Types for representing the size of objects in memory.
2
3use core::fmt::Display;
4
5/// The size of an object in memory, in bytes.
6///
7/// The helper methods on this type use powers of 2 for conversions between units,
8/// consistent with the standards for memory reporting.
9///
10/// While it would technically be more correct to use e.g.
11/// "kibibytes" instead of "kilobytes", "mebibytes" instead of "megabytes", etc.,
12/// the more common terms are used here for familiarity and discoverability.
13#[derive(#[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
    for MemorySize {
}
#[automatically_derived]impl ::core::clone::Clone for MemorySize {
    #[inline]
    fn clone(&self) -> Self {
        let _: ::core::clone::AssertParamIsClone<u64>;
        *self
    }
}Clone, #[automatically_derived]impl ::core::marker::Copy for MemorySize { }Copy, #[automatically_derived]impl ::core::fmt::Debug for MemorySize {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f, "MemorySize",
            &&self.0)
    }
}Debug, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
    MemorySize {
}
#[automatically_derived]impl ::core::cmp::PartialEq for MemorySize {
    #[inline]
    fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]impl ::core::cmp::Eq for MemorySize {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<u64>;
    }
}Eq, #[automatically_derived]impl ::core::cmp::PartialOrd for MemorySize {
    #[inline]
    fn partial_cmp(&self, other: &Self)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
    }
}PartialOrd, #[automatically_derived]impl ::core::cmp::Ord for MemorySize {
    #[inline]
    fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
        ::core::cmp::Ord::cmp(&self.0, &other.0)
    }
}Ord)]
14#[cfg_attr(feature = "serialize", derive(#[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 MemorySize {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private229::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                _serde::Serializer::serialize_newtype_struct(__serializer,
                    "MemorySize", &self.0)
            }
        }
    };serde::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 MemorySize {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private229::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private229::PhantomData<MemorySize>,
                    lifetime: _serde::__private229::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = MemorySize;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private229::Formatter)
                        -> _serde::__private229::fmt::Result {
                        _serde::__private229::Formatter::write_str(__formatter,
                            "tuple struct MemorySize")
                    }
                    #[inline]
                    fn visit_newtype_struct<__E>(self, __e: __E)
                        -> _serde::__private229::Result<Self::Value, __E::Error>
                        where __E: _serde::Deserializer<'de> {
                        let __field0: u64 =
                            <u64 as _serde::Deserialize>::deserialize(__e)?;
                        _serde::__private229::Ok(MemorySize(__field0))
                    }
                    #[inline]
                    fn visit_seq<__A>(self, mut __seq: __A)
                        -> _serde::__private229::Result<Self::Value, __A::Error>
                        where __A: _serde::de::SeqAccess<'de> {
                        let __field0 =
                            match _serde::de::SeqAccess::next_element::<u64>(&mut __seq)?
                                {
                                _serde::__private229::Some(__value) => __value,
                                _serde::__private229::None =>
                                    return _serde::__private229::Err(_serde::de::Error::invalid_length(0usize,
                                                &"tuple struct MemorySize with 1 element")),
                            };
                        _serde::__private229::Ok(MemorySize(__field0))
                    }
                }
                _serde::Deserializer::deserialize_newtype_struct(__deserializer,
                    "MemorySize",
                    __Visitor {
                        marker: _serde::__private229::PhantomData::<MemorySize>,
                        lifetime: _serde::__private229::PhantomData,
                    })
            }
        }
    };serde::Deserialize))]
15pub struct MemorySize(pub u64);
16
17impl MemorySize {
18    /// Creates a new [`MemorySize`] from the given number of bytes.
19    ///
20    /// This method is provided for convenience,
21    /// as many other APIs in Rust use `usize` for sizes and counts.
22    /// To initialize this type with a `u64`, just call `MemorySize(bytes)` directly.
23    pub fn new(bytes: usize) -> Self {
24        MemorySize(bytes as u64)
25    }
26
27    /// Returns the size in bytes, as a `usize`.
28    ///
29    /// This method is provided for convenience,
30    /// as many other APIs in Rust use `usize` for sizes and counts.
31    /// To access the value as a `u64`, just use the `.0` field directly.
32    ///
33    /// 1 byte = 8 bits.
34    pub fn as_bytes(&self) -> usize {
35        self.0 as usize
36    }
37
38    /// Returns the size in kilobytes.
39    ///
40    /// 1 kilobyte = 1024 bytes.
41    pub fn as_kilobytes(&self) -> f64 {
42        self.0 as f64 / 1024.0
43    }
44
45    /// Returns the size in megabytes.
46    ///
47    /// 1 megabyte = 1024 kilobytes.
48    pub fn as_megabytes(&self) -> f64 {
49        self.0 as f64 / (1024.0 * 1024.0)
50    }
51
52    /// Returns the size in gigabytes.
53    ///
54    /// 1 gigabyte = 1024 megabytes.
55    pub fn as_gigabytes(&self) -> f64 {
56        self.0 as f64 / (1024.0 * 1024.0 * 1024.0)
57    }
58
59    /// Returns the size in terabytes.
60    ///
61    /// 1 terabyte = 1024 gigabytes.
62    pub fn as_terabytes(&self) -> f64 {
63        self.0 as f64 / (1024.0 * 1024.0 * 1024.0 * 1024.0)
64    }
65
66    /// Determine the appropriate unit for displaying the memory size.
67    ///
68    /// Units are chosen such that the value is at least 1 in that unit.
69    ///
70    /// This is used for formatting the memory size in a human-readable way,
71    /// such as in the [`Display`] implementation for this type.
72    pub fn appropriate_unit(&self) -> MemoryUnit {
73        if self.0 >= 1024 * 1024 * 1024 * 1024 {
74            MemoryUnit::Terabytes
75        } else if self.0 >= 1024 * 1024 * 1024 {
76            MemoryUnit::Gigabytes
77        } else if self.0 >= 1024 * 1024 {
78            MemoryUnit::Megabytes
79        } else if self.0 >= 1024 {
80            MemoryUnit::Kilobytes
81        } else {
82            MemoryUnit::Bytes
83        }
84    }
85}
86
87impl Display for MemorySize {
88    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
89        let unit = self.appropriate_unit();
90        match unit {
91            MemoryUnit::Bytes => f.write_fmt(format_args!("{0} B", self.as_bytes()))write!(f, "{} B", self.as_bytes()),
92            MemoryUnit::Kilobytes => f.write_fmt(format_args!("{0:.2} KiB", self.as_kilobytes()))write!(f, "{:.2} KiB", self.as_kilobytes()),
93            MemoryUnit::Megabytes => f.write_fmt(format_args!("{0:.2} MiB", self.as_megabytes()))write!(f, "{:.2} MiB", self.as_megabytes()),
94            MemoryUnit::Gigabytes => f.write_fmt(format_args!("{0:.2} GiB", self.as_gigabytes()))write!(f, "{:.2} GiB", self.as_gigabytes()),
95            MemoryUnit::Terabytes => f.write_fmt(format_args!("{0:.2} TiB", self.as_terabytes()))write!(f, "{:.2} TiB", self.as_terabytes()),
96        }
97    }
98}
99
100/// Common units for representing memory size.
101///
102/// Used for determining the most appropriate unit to display a [`MemorySize`].
103#[derive(#[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
    for MemoryUnit {
}
#[automatically_derived]impl ::core::clone::Clone for MemoryUnit {
    #[inline]
    fn clone(&self) -> Self { *self }
}Clone, #[automatically_derived]impl ::core::marker::Copy for MemoryUnit { }Copy, #[automatically_derived]impl ::core::fmt::Debug for MemoryUnit {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_c_like_enum_write_str(f,
            "Bytes Kilobytes Megabytes Gigabytes Terabytes",
            match self {
                MemoryUnit::Bytes => 0usize,
                MemoryUnit::Kilobytes => 6usize,
                MemoryUnit::Megabytes => 16usize,
                MemoryUnit::Gigabytes => 26usize,
                MemoryUnit::Terabytes => 36usize,
            })
    }
}Debug, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
    MemoryUnit {
}
#[automatically_derived]impl ::core::cmp::PartialEq for MemoryUnit {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        ::core::intrinsics::discriminant_value(self) ==
            ::core::intrinsics::discriminant_value(other)
    }
}PartialEq, #[automatically_derived]impl ::core::cmp::Eq for MemoryUnit { }Eq)]
104pub enum MemoryUnit {
105    /// 8 bits
106    Bytes,
107    /// 1 kilobyte = 1024 bytes
108    Kilobytes,
109    /// 1 megabyte = 1024 kilobytes
110    Megabytes,
111    /// 1 gigabyte = 1024 megabytes
112    Gigabytes,
113    /// 1 terabyte = 1024 gigabytes
114    Terabytes,
115}