ferritin_core/views/
chain.rs1use super::residue::ResidueView;
2use crate::AtomCollection;
3
4pub struct ChainView<'a> {
6 pub(crate) data: &'a AtomCollection,
7 pub(crate) start_residue_idx: usize,
8 pub(crate) end_residue_idx: usize,
9}
10
11impl<'a> ChainView<'a> {
12 pub fn chain_id(&self) -> &str {
13 let residue_starts = self.data.get_residue_start_indices().unwrap();
15 let first_atom_idx = residue_starts[self.start_residue_idx] as usize;
16 self.data.get_chain_id(first_atom_idx)
17 }
18 pub fn iter_residues(&self) -> impl Iterator<Item = ResidueView<'_>> {
19 let residue_indices = self.data.get_residue_start_indices().unwrap();
20 let chain_id = self.chain_id();
21
22 let atom_indices: Vec<usize> = (self.start_residue_idx
24 ..=self
25 .end_residue_idx
26 .min(residue_indices.len().saturating_sub(1)))
27 .map(|idx| residue_indices[idx] as usize)
28 .collect();
29
30 let last_residue_end_idx = if self.end_residue_idx < residue_indices.len().saturating_sub(1)
32 {
33 residue_indices[self.end_residue_idx + 1] as usize
35 } else {
36 self.data.get_size()
38 };
39
40 let mut residues = Vec::new();
42
43 for i in 0..atom_indices.len().saturating_sub(1) {
45 let start_idx = atom_indices[i];
46 let end_idx = atom_indices[i + 1];
47
48 if self.data.get_chain_id(start_idx) == chain_id {
50 residues.push(ResidueView::new(self.data, start_idx, end_idx));
51 }
52 }
53
54 if let Some(&last_idx) = atom_indices.last() {
56 if self.data.get_chain_id(last_idx) == chain_id {
57 residues.push(ResidueView::new(self.data, last_idx, last_residue_end_idx));
58 }
59 }
60
61 residues.into_iter()
62 }
63 pub fn residue_count(&self) -> usize {
65 self.iter_residues().count()
66 }
67}