use crate::unit::Unit;
use std::collections::{btree_map, BTreeMap};
#[derive(Default)]
pub struct Powers {
powers: BTreeMap<Unit, i32>,
}
impl Powers {
pub fn is_empty(&self) -> bool {
self.powers.is_empty()
}
pub fn len(&self) -> usize {
self.powers.len()
}
pub fn clear(&mut self) {
self.powers.clear();
}
pub fn get(&self, unit: Unit) -> Option<i32> {
self.powers.get(&unit).copied()
}
pub fn insert(&mut self, unit: Unit, power: i32) {
match self.powers.entry(unit) {
btree_map::Entry::Vacant(e) => {
e.insert(power);
}
btree_map::Entry::Occupied(mut e) => {
*e.get_mut() += power;
}
}
}
pub fn iter(&self) -> Iter<'_> {
Iter {
iter: self.powers.iter(),
}
}
}
impl<'a> IntoIterator for &'a Powers {
type Item = (Unit, i32);
type IntoIter = Iter<'a>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl IntoIterator for Powers {
type Item = (Unit, i32);
type IntoIter = IntoIter;
fn into_iter(self) -> Self::IntoIter {
IntoIter {
iter: self.powers.into_iter(),
}
}
}
pub struct Iter<'a> {
iter: btree_map::Iter<'a, Unit, i32>,
}
impl<'a> Iterator for Iter<'a> {
type Item = (Unit, i32);
fn next(&mut self) -> Option<Self::Item> {
let (unit, power) = self.iter.next()?;
Some((*unit, *power))
}
}
pub struct IntoIter {
iter: btree_map::IntoIter<Unit, i32>,
}
impl Iterator for IntoIter {
type Item = (Unit, i32);
fn next(&mut self) -> Option<Self::Item> {
self.iter.next()
}
}