use molframe_core::structure::StructureData;
pub(super) fn same_topology(left: &StructureData, right: &StructureData) -> bool {
if atom_count(left) != atom_count(right)
|| left.topology.residues.len() != right.topology.residues.len()
|| left.topology.chains.len() != right.topology.chains.len()
{
return false;
}
left.bonds.iter().eq(right.bonds.iter())
&& same_chain_topology(left, right)
&& same_residue_topology(left, right)
&& same_atom_topology(left, right)
}
pub(super) fn atom_count(data: &StructureData) -> u32 {
data.chunks.last().map_or(0, |chunk| chunk.atoms().end)
}
pub(super) fn same_chain_topology(left: &StructureData, right: &StructureData) -> bool {
left.chains().zip(right.chains()).all(|(left, right)| {
left.label() == right.label()
&& left.auth_label() == right.auth_label()
&& left.polymer_kind() == right.polymer_kind()
})
}
pub(super) fn same_residue_topology(left: &StructureData, right: &StructureData) -> bool {
left.residues().zip(right.residues()).all(|(left, right)| {
left.name() == right.name()
&& left.auth_seq_id() == right.auth_seq_id()
&& left.label_seq_id() == right.label_seq_id()
&& left.ins_code() == right.ins_code()
&& left.is_het() == right.is_het()
})
}
pub(super) fn same_atom_topology(left: &StructureData, right: &StructureData) -> bool {
left.atoms().zip(right.atoms()).all(|(left, right)| {
left.name() == right.name()
&& left.element() == right.element()
&& left.alt_label() == right.alt_label()
&& left.formal_charge() == right.formal_charge()
})
}