use std::ops::{BitAnd, BitOr, Sub};
use molframe_core::index::{AtomIndex, ModelIndex};
use molframe_core::selection::AtomSelection;
use molframe_core::structure::{AtomRef, StructureView};
use super::handle::Structure;
#[derive(Clone, Debug)]
pub struct Selection(StructureView);
impl Selection {
#[must_use]
pub fn len(&self) -> u64 {
self.0.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
#[must_use]
pub fn is_stale_for(&self, structure: &Structure) -> bool {
self.0.is_stale_for(structure.engine())
}
pub fn atoms(&self) -> impl Iterator<Item = AtomRef<'_>> + '_ {
let data = self.0.data();
self.0
.selection()
.iter()
.filter_map(move |atom| data.atom(AtomIndex::new(atom)))
}
#[must_use]
pub fn to_coordinates(&self, model: ModelIndex) -> Vec<[f32; 3]> {
self.0.positions(model).collect()
}
pub(crate) fn atom_selection(&self) -> &AtomSelection {
self.0.selection()
}
}
impl From<StructureView> for Selection {
fn from(view: StructureView) -> Self {
Self(view)
}
}
impl BitOr for &Selection {
type Output = Selection;
fn bitor(self, rhs: Self) -> Selection {
Selection(self.0.union(&rhs.0))
}
}
impl BitAnd for &Selection {
type Output = Selection;
fn bitand(self, rhs: Self) -> Selection {
Selection(self.0.intersect(&rhs.0))
}
}
impl Sub for &Selection {
type Output = Selection;
fn sub(self, rhs: Self) -> Selection {
Selection(self.0.difference(&rhs.0))
}
}