molframe_core/topology/
model.rs1use super::csr::stored_range;
4use crate::index::ModelIndex;
5use crate::limits::{CapacityError, TableError};
6use std::ops::Range;
7use std::sync::Arc;
8
9#[derive(Clone, Debug, Default)]
11pub struct ModelTable {
12 first_chain: Arc<Vec<u32>>,
13 chain_count: Arc<Vec<u32>>,
14 model_num: Arc<Vec<i32>>,
15}
16
17impl ModelTable {
18 #[must_use]
20 pub fn len(&self) -> usize {
21 self.model_num.len()
22 }
23
24 #[must_use]
26 pub fn is_empty(&self) -> bool {
27 self.model_num.is_empty()
28 }
29
30 pub fn push(&mut self, model_num: i32, chains: Range<u32>) -> Result<ModelIndex, TableError> {
36 let position = u32::try_from(self.model_num.len())
37 .map_err(|_| TableError::Capacity(CapacityError::new("model table")))?;
38 let chain_count = chains
39 .end
40 .checked_sub(chains.start)
41 .ok_or(TableError::ReversedRange { table: "model" })?;
42 Arc::make_mut(&mut self.first_chain).push(chains.start);
43 Arc::make_mut(&mut self.chain_count).push(chain_count);
44 Arc::make_mut(&mut self.model_num).push(model_num);
45 Ok(ModelIndex::new(position))
46 }
47
48 #[must_use]
54 pub fn model_num(&self, model: ModelIndex) -> Option<i32> {
55 self.model_num.get(model.as_usize()).copied()
56 }
57
58 #[must_use]
60 pub fn chains(&self, model: ModelIndex) -> Option<Range<u32>> {
61 stored_range(&self.first_chain, &self.chain_count, model.as_usize())
62 }
63
64 pub fn iter(&self) -> impl Iterator<Item = ModelIndex> + '_ {
67 self.model_num
68 .iter()
69 .enumerate()
70 .filter_map(|(position, _)| u32::try_from(position).ok().map(ModelIndex::new))
71 }
72}