ferritin_core/selection/
selection.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
//! Combine Selections

use std::ops::BitAnd;

/// Selection
///
/// Selection are indices that can be use used to
/// identify specific sets of atoms within an [`AtomCollection`]
///
#[derive(Clone, Debug)]
pub struct Selection {
    pub(crate) indices: Vec<usize>,
}

impl Selection {
    pub fn new(indices: Vec<usize>) -> Self {
        Selection { indices }
    }

    pub fn and(&self, other: &Selection) -> Selection {
        let indices: Vec<usize> = self
            .indices
            .iter()
            .filter(|&&idx| other.indices.contains(&idx))
            .cloned()
            .collect();
        Selection::new(indices)
    }
    // Add union operation
    pub fn or(&self, other: &Selection) -> Selection {
        let mut indices = self.indices.clone();
        indices.extend(
            other
                .indices
                .iter()
                .filter(|idx| !self.indices.contains(idx)),
        );
        indices.sort();
        Selection::new(indices)
    }

    // Add difference operation
    pub fn not(&self, other: &Selection) -> Selection {
        let indices: Vec<_> = self
            .indices
            .iter()
            .filter(|&&idx| !other.indices.contains(&idx))
            .cloned()
            .collect();
        Selection::new(indices)
    }
}

impl BitAnd for &Selection {
    type Output = Selection;

    fn bitand(self, other: Self) -> Selection {
        self.and(other)
    }
}