use std::fmt;
use std::slice;
use crate::OxidationStateAssignment;
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct OxidationStateSet {
assignments: Vec<OxidationStateAssignment>,
}
impl OxidationStateSet {
#[must_use]
pub const fn new() -> Self {
Self {
assignments: Vec::new(),
}
}
#[must_use]
pub fn from_assignments(
assignments: impl IntoIterator<Item = OxidationStateAssignment>,
) -> Self {
let mut set = Self::new();
for assignment in assignments {
set.insert(assignment);
}
set
}
pub fn insert(
&mut self,
assignment: OxidationStateAssignment,
) -> Option<OxidationStateAssignment> {
if let Some(existing) = self
.assignments
.iter_mut()
.find(|existing| existing.label() == assignment.label())
{
return Some(std::mem::replace(existing, assignment));
}
self.assignments.push(assignment);
None
}
#[must_use]
pub fn get(&self, label: &str) -> Option<&OxidationStateAssignment> {
let label = label.trim();
self.assignments
.iter()
.find(|assignment| assignment.label() == label)
}
#[must_use]
pub fn contains_label(&self, label: &str) -> bool {
self.get(label).is_some()
}
#[must_use]
pub fn len(&self) -> usize {
self.assignments.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.assignments.is_empty()
}
pub fn iter(&self) -> slice::Iter<'_, OxidationStateAssignment> {
self.assignments.iter()
}
}
impl fmt::Display for OxidationStateSet {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut assignments = self.assignments.iter();
let Some(first) = assignments.next() else {
return Ok(());
};
write!(formatter, "{first}")?;
for assignment in assignments {
write!(formatter, ", {assignment}")?;
}
Ok(())
}
}
impl IntoIterator for OxidationStateSet {
type IntoIter = std::vec::IntoIter<Self::Item>;
type Item = OxidationStateAssignment;
fn into_iter(self) -> Self::IntoIter {
self.assignments.into_iter()
}
}
impl<'a> IntoIterator for &'a OxidationStateSet {
type IntoIter = slice::Iter<'a, OxidationStateAssignment>;
type Item = &'a OxidationStateAssignment;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}