Repository: bevyengine/bevy
File: crates/bevy_mesh/src/mesh.rs (Rust)

Code before:
        Ok(self)
    }

    /// Remove duplicate vertices and create the index pointing to the unique vertices.
    ///
    /// This function is no-op if the mesh already has [`Indices`] set,
    /// even if there are duplicate vertices. If deduplication is needed with indices already set,
    /// consider calling [`Mesh::duplicate_vertices`] and then this function.
    ///
    /// # Panics
    /// Panics when the mesh data has already been extracted to `RenderWorld`. To handle
    /// this as an error use [`Mesh::try_deduplicate_vertices`]
    pub fn deduplicate_vertices(&mut self) {
        self.try_deduplicate_vertices().expect(MESH_EXTRACTED_ERROR);
    }

    /// Remove duplicate vertices and create the index pointing to the unique vertices.
    ///
    /// This function is no-op if the mesh already has [`Indices`] set,
    /// even if there are duplicate vertices. If deduplication is needed with indices already set,
    /// consider calling [`Mesh::duplicate_vertices`] and then this function.
    ///
    /// Returns an error if the mesh data has been extracted to `RenderWorld`.
    pub fn try_deduplicate_vertices(&mut self) -> Result<(), MeshAccessError> {
        match self.try_indices() {
            Ok(_) => return Ok(()), // explicit no-op
            Err(err) => match err {
                MeshAccessError::ExtractedToRenderWorld => return Err(err),
                MeshAccessError::NotFound => (),
            },
        }

        #[derive(Copy, Clone)]
        struct VertexRef<'a> {
            mesh_attributes: &'a BTreeMap<MeshVertexAttributeId, MeshAttributeData>,
            i: usize,
        }
        impl<'a> VertexRef<'a> {
            fn push_to(&self, target: &mut BTreeMap<MeshVertexAttributeId, MeshAttributeData>) {
                for (key, this_attribute_data) in self.mesh_attributes.iter() {
                    let target_attribute_data = target.get_mut(key).unwrap(); // ok to unwrap, all keys added to new_attributes below
                    target_attribute_data
                        .values
                        .push_from(&this_attribute_data.values, self.i);
                }
            }
        }
        impl<'a> PartialEq for VertexRef<'a> {
            fn eq(&self, other: &Self) -> bool {
                assert!(ptr::eq(self.mesh_attributes, other.mesh_attributes));
                for values in self.mesh_attributes.values() {

Review comment (bug):
I don't like this API design, even if it's documented. This is a failure mode, and should a distinct error variant.

Code after:
        Ok(self)
    }

    /// Remove duplicate vertices and create the index pointing to the unique vertices.
    ///
    /// Returns an error if the mesh data has been extracted to `RenderWorld`.
    /// Returns an error if the mesh already has [`Indices`] set, even if there
    /// are duplicate vertices. If deduplication is needed with indices already set,
    /// consider calling [`Mesh::duplicate_vertices`] and then this function.
    pub fn merge_duplicate_vertices(&mut self) -> Result<(), MeshMergeDuplicateVerticesError> {
        match self.try_indices() {
            Ok(_) => return Err(MeshMergeDuplicateVerticesError::IndicesAlreadySet),
            Err(err) => match err {
                MeshAccessError::ExtractedToRenderWorld => return Err(err.into()),
                MeshAccessError::NotFound => (),
            },
        }

        #[derive(Copy, Clone)]
        struct VertexRef<'a> {
            mesh_attributes: &'a BTreeMap<MeshVertexAttributeId, MeshAttributeData>,
            i: usize,
        }
        impl<'a> VertexRef<'a> {
            fn push_to(&self, target: &mut BTreeMap<MeshVertexAttributeId, MeshAttributeData>) {
                for (key, this_attribute_data) in self.mesh_attributes.iter() {
                    let target_attribute_data = target.get_mut(key).unwrap(); // ok to unwrap, all keys added to new_attributes below
                    target_attribute_data
                        .values
                        .push_from(&this_attribute_data.values, self.i);
                }
            }
        }
        impl<'a> PartialEq for VertexRef<'a> {
            fn eq(&self, other: &Self) -> bool {
                assert!(ptr::eq(self.mesh_attributes, other.mesh_attributes));
                for values in self.mesh_attributes.values() {
                    if values.values.get_bytes_at(self.i) != values.values.get_bytes_at(other.i) {
                        return false;
                    }
                }
                true
            }
        }
        impl<'a> Eq for VertexRef<'a> {}
        impl<'a> Hash for VertexRef<'a> {
            fn hash<H: Hasher>(&self, state: &mut H) {
                for values in self.mesh_attributes.values() {
                    values.values.get_bytes_at(self.i).hash(state);
                }
            }