1use bevy_reflect::Reflect;
2use core::iter;
3use core::iter::FusedIterator;
4#[cfg(feature = "serialize")]
5use serde::{Deserialize, Serialize};
6use thiserror::Error;
7use wgpu_types::IndexFormat;
8
9use crate::MeshAccessError;
10
11pub(crate) enum FourIterators<A, B, C, D> {
15 First(A),
16 Second(B),
17 Third(C),
18 Fourth(D),
19}
20
21impl<A, B, C, D, I> Iterator for FourIterators<A, B, C, D>
22where
23 A: Iterator<Item = I>,
24 B: Iterator<Item = I>,
25 C: Iterator<Item = I>,
26 D: Iterator<Item = I>,
27{
28 type Item = I;
29
30 fn next(&mut self) -> Option<Self::Item> {
31 match self {
32 FourIterators::First(iter) => iter.next(),
33 FourIterators::Second(iter) => iter.next(),
34 FourIterators::Third(iter) => iter.next(),
35 FourIterators::Fourth(iter) => iter.next(),
36 }
37 }
38
39 fn size_hint(&self) -> (usize, Option<usize>) {
40 match self {
41 FourIterators::First(iter) => iter.size_hint(),
42 FourIterators::Second(iter) => iter.size_hint(),
43 FourIterators::Third(iter) => iter.size_hint(),
44 FourIterators::Fourth(iter) => iter.size_hint(),
45 }
46 }
47}
48
49#[derive(#[automatically_derived]
impl ::core::fmt::Debug for MeshWindingInvertError {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
MeshWindingInvertError::WrongTopology =>
::core::fmt::Formatter::write_str(f, "WrongTopology"),
MeshWindingInvertError::AbruptIndicesEnd =>
::core::fmt::Formatter::write_str(f, "AbruptIndicesEnd"),
MeshWindingInvertError::MeshAccessError(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"MeshAccessError", &__self_0),
}
}
}Debug, fn from(source: MeshAccessError) -> Self {
MeshWindingInvertError::MeshAccessError { 0: source }
}Error)]
51pub enum MeshWindingInvertError {
52 #[error("Mesh winding inversion does not work for primitive topology `PointList`")]
54 WrongTopology,
55
56 #[error("Indices weren't in chunks according to topology")]
60 AbruptIndicesEnd,
61 #[error("Mesh access error: {0}")]
62 MeshAccessError(#[from] MeshAccessError),
63}
64
65#[derive(#[automatically_derived]
impl ::core::fmt::Debug for MeshTrianglesError {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
MeshTrianglesError::WrongTopology =>
::core::fmt::Formatter::write_str(f, "WrongTopology"),
MeshTrianglesError::PositionsFormat =>
::core::fmt::Formatter::write_str(f, "PositionsFormat"),
MeshTrianglesError::BadIndices =>
::core::fmt::Formatter::write_str(f, "BadIndices"),
MeshTrianglesError::MeshAccessError(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"MeshAccessError", &__self_0),
}
}
}Debug, fn from(source: MeshAccessError) -> Self {
MeshTrianglesError::MeshAccessError { 0: source }
}Error)]
67pub enum MeshTrianglesError {
68 #[error("Source mesh does not have primitive topology TriangleList or TriangleStrip")]
69 WrongTopology,
70
71 #[error("Source mesh position data is not Float32x3")]
72 PositionsFormat,
73
74 #[error("Face index data references vertices that do not exist")]
75 BadIndices,
76 #[error("mesh access error: {0}")]
77 MeshAccessError(#[from] MeshAccessError),
78}
79
80#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Indices {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Indices::U16(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "U16",
&__self_0),
Indices::U32(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "U32",
&__self_0),
}
}
}Debug, #[automatically_derived]
impl ::core::clone::Clone for Indices {
#[inline]
fn clone(&self) -> Indices {
match self {
Indices::U16(__self_0) =>
Indices::U16(::core::clone::Clone::clone(__self_0)),
Indices::U32(__self_0) =>
Indices::U32(::core::clone::Clone::clone(__self_0)),
}
}
}Clone, const _: () =
{
impl bevy_reflect::GetTypeRegistration for Indices where {
fn get_type_registration() -> bevy_reflect::TypeRegistration {
let mut registration =
bevy_reflect::TypeRegistration::of::<Self>();
registration.insert::<bevy_reflect::ReflectFromPtr>(bevy_reflect::FromType::<Self>::from_type());
registration.insert::<bevy_reflect::ReflectFromReflect>(bevy_reflect::FromType::<Self>::from_type());
registration
}
#[inline(never)]
fn register_type_dependencies(registry:
&mut bevy_reflect::TypeRegistry) {
<Vec<u16> as
bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
<Vec<u32> as
bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
}
}
impl bevy_reflect::Typed for Indices where {
#[inline]
fn type_info() -> &'static bevy_reflect::TypeInfo {
static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
bevy_reflect::utility::NonGenericTypeInfoCell::new();
CELL.get_or_set(||
{
bevy_reflect::TypeInfo::Enum(bevy_reflect::enums::EnumInfo::new::<Self>(&[bevy_reflect::enums::VariantInfo::Tuple(bevy_reflect::enums::TupleVariantInfo::new("U16",
&[bevy_reflect::UnnamedField::new::<Vec<u16>>(0usize)])),
bevy_reflect::enums::VariantInfo::Tuple(bevy_reflect::enums::TupleVariantInfo::new("U32",
&[bevy_reflect::UnnamedField::new::<Vec<u32>>(0usize)]))]))
})
}
}
#[allow(deprecated, reason =
"derives on a deprecated type shouldn't be considered a usage")]
impl bevy_reflect::TypePath for Indices where {
fn type_path() -> &'static str { "bevy_mesh::index::Indices" }
fn short_type_path() -> &'static str { "Indices" }
fn type_ident() -> ::core::option::Option<&'static str> {
::core::option::Option::Some("Indices")
}
fn crate_name() -> ::core::option::Option<&'static str> {
::core::option::Option::Some("bevy_mesh::index".split(':').next().unwrap())
}
fn module_path() -> ::core::option::Option<&'static str> {
::core::option::Option::Some("bevy_mesh::index")
}
}
impl bevy_reflect::Reflect for Indices where {
#[inline]
fn into_any(self:
bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
->
bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
self
}
#[inline]
fn as_any(&self) -> &dyn ::core::any::Any { self }
#[inline]
fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
#[inline]
fn into_reflect(self:
bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
->
bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
self
}
#[inline]
fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
#[inline]
fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
self
}
#[inline]
fn set(&mut self,
value:
bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
->
::core::result::Result<(),
bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
*self = <dyn bevy_reflect::Reflect>::take(value)?;
::core::result::Result::Ok(())
}
}
#[allow(non_upper_case_globals)]
const _: () =
{
static __INVENTORY: ::inventory::Node =
::inventory::Node {
value: &{
bevy_reflect::__macro_exports::auto_register::AutomaticReflectRegistrations(<Indices
as
bevy_reflect::__macro_exports::auto_register::RegisterForReflection>::__register)
},
next: ::inventory::__private::UnsafeCell::new(::inventory::__private::Option::None),
};
#[link_section = ".text.startup"]
unsafe extern "C" fn __ctor() {
unsafe {
::inventory::ErasedNode::submit(__INVENTORY.value,
&__INVENTORY)
}
}
#[used]
#[link_section = ".init_array"]
static __CTOR: unsafe extern "C" fn() = __ctor;
};
impl bevy_reflect::enums::Enum for Indices where {
fn field(&self, __name_param: &str)
-> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
match self { _ => ::core::option::Option::None, }
}
fn field_at(&self, __index_param: usize)
-> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
match self {
Indices::U16 { 0: __value, .. } if __index_param == 0usize
=> ::core::option::Option::Some(__value),
Indices::U32 { 0: __value, .. } if __index_param == 0usize
=> ::core::option::Option::Some(__value),
_ => ::core::option::Option::None,
}
}
fn field_mut(&mut self, __name_param: &str)
->
::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
match self { _ => ::core::option::Option::None, }
}
fn field_at_mut(&mut self, __index_param: usize)
->
::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
match self {
Indices::U16 { 0: __value, .. } if __index_param == 0usize
=> ::core::option::Option::Some(__value),
Indices::U32 { 0: __value, .. } if __index_param == 0usize
=> ::core::option::Option::Some(__value),
_ => ::core::option::Option::None,
}
}
fn index_of(&self, __name_param: &str)
-> ::core::option::Option<usize> {
match self { _ => ::core::option::Option::None, }
}
fn name_at(&self, __index_param: usize)
-> ::core::option::Option<&str> {
match self { _ => ::core::option::Option::None, }
}
fn iter_fields(&self) -> bevy_reflect::enums::VariantFieldIter {
bevy_reflect::enums::VariantFieldIter::new(self)
}
#[inline]
fn field_len(&self) -> usize {
match self {
Indices::U16 { .. } => 1usize,
Indices::U32 { .. } => 1usize,
_ => 0,
}
}
#[inline]
fn variant_name(&self) -> &str {
match self {
Indices::U16 { .. } => "U16",
Indices::U32 { .. } => "U32",
_ =>
::core::panicking::panic("internal error: entered unreachable code"),
}
}
#[inline]
fn variant_index(&self) -> usize {
match self {
Indices::U16 { .. } => 0usize,
Indices::U32 { .. } => 1usize,
_ =>
::core::panicking::panic("internal error: entered unreachable code"),
}
}
#[inline]
fn variant_type(&self) -> bevy_reflect::enums::VariantType {
match self {
Indices::U16 { .. } =>
bevy_reflect::enums::VariantType::Tuple,
Indices::U32 { .. } =>
bevy_reflect::enums::VariantType::Tuple,
_ =>
::core::panicking::panic("internal error: entered unreachable code"),
}
}
fn to_dynamic_enum(&self) -> bevy_reflect::enums::DynamicEnum {
bevy_reflect::enums::DynamicEnum::from_ref::<Self>(self)
}
}
impl bevy_reflect::PartialReflect for Indices where {
#[inline]
fn get_represented_type_info(&self)
-> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
::core::option::Option::Some(<Self as
bevy_reflect::Typed>::type_info())
}
#[inline]
fn try_apply(&mut self,
__value_param: &dyn bevy_reflect::PartialReflect)
-> ::core::result::Result<(), bevy_reflect::ApplyError> {
if let bevy_reflect::ReflectRef::Enum(__value_param) =
bevy_reflect::PartialReflect::reflect_ref(__value_param) {
if bevy_reflect::enums::Enum::variant_name(self) ==
bevy_reflect::enums::Enum::variant_name(__value_param) {
match bevy_reflect::enums::Enum::variant_type(__value_param)
{
bevy_reflect::enums::VariantType::Struct => {
for field in
bevy_reflect::enums::Enum::iter_fields(__value_param) {
let name = field.name().unwrap();
if let ::core::option::Option::Some(v) =
bevy_reflect::enums::Enum::field_mut(self, name) {
bevy_reflect::PartialReflect::try_apply(v, field.value())?;
}
}
}
bevy_reflect::enums::VariantType::Tuple => {
for (index, field) in
::core::iter::Iterator::enumerate(bevy_reflect::enums::Enum::iter_fields(__value_param))
{
if let ::core::option::Option::Some(v) =
bevy_reflect::enums::Enum::field_at_mut(self, index) {
bevy_reflect::PartialReflect::try_apply(v, field.value())?;
}
}
}
_ => {}
}
} else {
match bevy_reflect::enums::Enum::variant_name(__value_param)
{
"U16" => {
*self =
Indices::U16 {
0: {
let __0 = __value_param.field_at(0usize);
let __0 =
__0.ok_or(bevy_reflect::ApplyError::MissingEnumField {
variant_name: ::core::convert::Into::into("U16"),
field_name: ::core::convert::Into::into(".0"),
})?;
<Vec<u16> as
bevy_reflect::FromReflect>::from_reflect(__0).ok_or(bevy_reflect::ApplyError::MismatchedTypes {
from_type: ::core::convert::Into::into(bevy_reflect::DynamicTypePath::reflect_type_path(__0)),
to_type: ::core::convert::Into::into(<Vec<u16> as
bevy_reflect::TypePath>::type_path()),
})?
},
}
}
"U32" => {
*self =
Indices::U32 {
0: {
let __0 = __value_param.field_at(0usize);
let __0 =
__0.ok_or(bevy_reflect::ApplyError::MissingEnumField {
variant_name: ::core::convert::Into::into("U32"),
field_name: ::core::convert::Into::into(".0"),
})?;
<Vec<u32> as
bevy_reflect::FromReflect>::from_reflect(__0).ok_or(bevy_reflect::ApplyError::MismatchedTypes {
from_type: ::core::convert::Into::into(bevy_reflect::DynamicTypePath::reflect_type_path(__0)),
to_type: ::core::convert::Into::into(<Vec<u32> as
bevy_reflect::TypePath>::type_path()),
})?
},
}
}
name => {
return ::core::result::Result::Err(bevy_reflect::ApplyError::UnknownVariant {
enum_name: ::core::convert::Into::into(bevy_reflect::DynamicTypePath::reflect_type_path(self)),
variant_name: ::core::convert::Into::into(name),
});
}
}
}
} else {
return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
from_kind: bevy_reflect::PartialReflect::reflect_kind(__value_param),
to_kind: bevy_reflect::ReflectKind::Enum,
});
}
::core::result::Result::Ok(())
}
fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
bevy_reflect::ReflectKind::Enum
}
fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
bevy_reflect::ReflectRef::Enum(self)
}
fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
bevy_reflect::ReflectMut::Enum(self)
}
fn reflect_owned(self:
bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
-> bevy_reflect::ReflectOwned {
bevy_reflect::ReflectOwned::Enum(self)
}
#[inline]
fn try_into_reflect(self:
bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
->
::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
::core::result::Result::Ok(self)
}
#[inline]
fn try_as_reflect(&self)
-> ::core::option::Option<&dyn bevy_reflect::Reflect> {
::core::option::Option::Some(self)
}
#[inline]
fn try_as_reflect_mut(&mut self)
-> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
::core::option::Option::Some(self)
}
#[inline]
fn into_partial_reflect(self:
bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
->
bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
self
}
#[inline]
fn as_partial_reflect(&self)
-> &dyn bevy_reflect::PartialReflect {
self
}
#[inline]
fn as_partial_reflect_mut(&mut self)
-> &mut dyn bevy_reflect::PartialReflect {
self
}
fn reflect_hash(&self) -> ::core::option::Option<u64> {
(bevy_reflect::enums::enum_hash)(self)
}
fn reflect_partial_eq(&self,
value: &dyn bevy_reflect::PartialReflect)
-> ::core::option::Option<bool> {
(bevy_reflect::enums::enum_partial_eq)(self, value)
}
fn reflect_partial_cmp(&self,
value: &dyn bevy_reflect::PartialReflect)
-> ::core::option::Option<::core::cmp::Ordering> {
(bevy_reflect::enums::enum_partial_cmp)(self, value)
}
#[inline]
fn reflect_clone(&self)
->
::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
bevy_reflect::ReflectCloneError> {
::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(::core::clone::Clone::clone(self)))
}
}
impl bevy_reflect::FromReflect for Indices where {
fn from_reflect(__param0: &dyn bevy_reflect::PartialReflect)
-> ::core::option::Option<Self> {
if let bevy_reflect::ReflectRef::Enum(__param0) =
bevy_reflect::PartialReflect::reflect_ref(__param0) {
match bevy_reflect::enums::Enum::variant_name(__param0) {
"U16" =>
::core::option::Option::Some(Indices::U16 {
0: {
let __0 = __param0.field_at(0usize);
let __0 = __0?;
<Vec<u16> as bevy_reflect::FromReflect>::from_reflect(__0)?
},
}),
"U32" =>
::core::option::Option::Some(Indices::U32 {
0: {
let __0 = __param0.field_at(0usize);
let __0 = __0?;
<Vec<u32> as bevy_reflect::FromReflect>::from_reflect(__0)?
},
}),
name => ::core::option::Option::None,
}
} else { ::core::option::Option::None }
}
}
};Reflect, #[automatically_derived]
impl ::core::cmp::PartialEq for Indices {
#[inline]
fn eq(&self, other: &Indices) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(Indices::U16(__self_0), Indices::U16(__arg1_0)) =>
__self_0 == __arg1_0,
(Indices::U32(__self_0), Indices::U32(__arg1_0)) =>
__self_0 == __arg1_0,
_ => unsafe { ::core::intrinsics::unreachable() }
}
}
}PartialEq)]
84#[reflect(Clone)]
85#[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 Indices {
fn serialize<__S>(&self, __serializer: __S)
-> _serde::__private228::Result<__S::Ok, __S::Error> where
__S: _serde::Serializer {
match *self {
Indices::U16(ref __field0) =>
_serde::Serializer::serialize_newtype_variant(__serializer,
"Indices", 0u32, "U16", __field0),
Indices::U32(ref __field0) =>
_serde::Serializer::serialize_newtype_variant(__serializer,
"Indices", 1u32, "U32", __field0),
}
}
}
};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 Indices {
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 {
"U16" => _serde::__private228::Ok(__Field::__field0),
"U32" => _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"U16" => _serde::__private228::Ok(__Field::__field0),
b"U32" => _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<Indices>,
lifetime: _serde::__private228::PhantomData<&'de ()>,
}
#[automatically_derived]
impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
type Value = Indices;
fn expecting(&self,
__formatter: &mut _serde::__private228::Formatter)
-> _serde::__private228::fmt::Result {
_serde::__private228::Formatter::write_str(__formatter,
"enum Indices")
}
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::__private228::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<u16>>(__variant),
Indices::U16),
(__Field::__field1, __variant) =>
_serde::__private228::Result::map(_serde::de::VariantAccess::newtype_variant::<Vec<u32>>(__variant),
Indices::U32),
}
}
}
#[doc(hidden)]
const VARIANTS: &'static [&'static str] = &["U16", "U32"];
_serde::Deserializer::deserialize_enum(__deserializer,
"Indices", VARIANTS,
__Visitor {
marker: _serde::__private228::PhantomData::<Indices>,
lifetime: _serde::__private228::PhantomData,
})
}
}
};Deserialize))]
86pub enum Indices {
87 U16(Vec<u16>),
88 U32(Vec<u32>),
89}
90
91impl Indices {
92 pub fn iter(&self) -> impl Iterator<Item = usize> + '_ {
94 match self {
95 Indices::U16(vec) => IndicesIter::U16(vec.iter()),
96 Indices::U32(vec) => IndicesIter::U32(vec.iter()),
97 }
98 }
99
100 pub fn len(&self) -> usize {
102 match self {
103 Indices::U16(vec) => vec.len(),
104 Indices::U32(vec) => vec.len(),
105 }
106 }
107
108 pub fn is_empty(&self) -> bool {
110 match self {
111 Indices::U16(vec) => vec.is_empty(),
112 Indices::U32(vec) => vec.is_empty(),
113 }
114 }
115
116 pub fn push(&mut self, index: u32) {
119 self.extend([index]);
120 }
121}
122
123impl Extend<u32> for Indices {
129 fn extend<T: IntoIterator<Item = u32>>(&mut self, iter: T) {
130 let mut iter = iter.into_iter();
131 match self {
132 Indices::U32(indices) => indices.extend(iter),
133 Indices::U16(indices) => {
134 indices.reserve(iter.size_hint().0);
135 while let Some(index) = iter.next() {
136 if index < u16::MAX as u32 {
137 indices.push(index as u16);
138 } else {
139 let new_vec = indices
140 .iter()
141 .map(|&index| u32::from(index))
142 .chain(iter::once(index))
143 .chain(iter)
144 .collect::<Vec<u32>>();
145 *self = Indices::U32(new_vec);
146 break;
147 }
148 }
149 }
150 }
151 }
152}
153
154enum IndicesIter<'a> {
156 U16(core::slice::Iter<'a, u16>),
157 U32(core::slice::Iter<'a, u32>),
158}
159
160impl Iterator for IndicesIter<'_> {
161 type Item = usize;
162
163 fn next(&mut self) -> Option<Self::Item> {
164 match self {
165 IndicesIter::U16(iter) => iter.next().map(|val| *val as usize),
166 IndicesIter::U32(iter) => iter.next().map(|val| *val as usize),
167 }
168 }
169
170 fn size_hint(&self) -> (usize, Option<usize>) {
171 match self {
172 IndicesIter::U16(iter) => iter.size_hint(),
173 IndicesIter::U32(iter) => iter.size_hint(),
174 }
175 }
176}
177
178impl<'a> ExactSizeIterator for IndicesIter<'a> {}
179
180impl<'a> FusedIterator for IndicesIter<'a> {}
181
182impl From<&Indices> for IndexFormat {
183 fn from(indices: &Indices) -> Self {
184 match indices {
185 Indices::U16(_) => IndexFormat::Uint16,
186 Indices::U32(_) => IndexFormat::Uint32,
187 }
188 }
189}
190
191#[cfg(test)]
192mod tests {
193 use crate::Indices;
194 use wgpu_types::IndexFormat;
195
196 #[test]
197 fn test_indices_push() {
198 let mut indices = Indices::U16(Vec::new());
199 indices.push(10);
200 assert_eq!(IndexFormat::Uint16, IndexFormat::from(&indices));
201 assert_eq!(vec![10], indices.iter().collect::<Vec<_>>());
202
203 indices.push(0x10000);
205 assert_eq!(IndexFormat::Uint32, IndexFormat::from(&indices));
206 assert_eq!(vec![10, 0x10000], indices.iter().collect::<Vec<_>>());
207
208 indices.push(20);
209 indices.push(0x20000);
210 assert_eq!(IndexFormat::Uint32, IndexFormat::from(&indices));
211 assert_eq!(
212 vec![10, 0x10000, 20, 0x20000],
213 indices.iter().collect::<Vec<_>>()
214 );
215 }
216
217 #[test]
218 fn test_indices_extend() {
219 let mut indices = Indices::U16(Vec::new());
220 indices.extend([10, 11]);
221 assert_eq!(IndexFormat::Uint16, IndexFormat::from(&indices));
222 assert_eq!(vec![10, 11], indices.iter().collect::<Vec<_>>());
223
224 indices.extend([12, 0x10013, 0x10014]);
226 assert_eq!(IndexFormat::Uint32, IndexFormat::from(&indices));
227 assert_eq!(
228 vec![10, 11, 12, 0x10013, 0x10014],
229 indices.iter().collect::<Vec<_>>()
230 );
231
232 indices.extend([15, 0x10016]);
233 assert_eq!(IndexFormat::Uint32, IndexFormat::from(&indices));
234 assert_eq!(
235 vec![10, 11, 12, 0x10013, 0x10014, 15, 0x10016],
236 indices.iter().collect::<Vec<_>>()
237 );
238 }
239}