Skip to main content

powerio_prob/
reference.rs

1use serde::{Deserialize, Serialize};
2
3use crate::Result;
4
5/// The reference (slack) buses of a problem instance, as dense bus indices in
6/// ascending order.
7///
8/// Every island of a network needs a reference bus, and the instance builders
9/// check that before they assemble, so a network of several islands gives
10/// several entries. A formulation grounds every entry. One that can ground
11/// only one bus calls [`single`](Self::single), which states the condition it
12/// needs instead of taking the first entry and grounding one island of many.
13#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
14#[serde(transparent)]
15pub struct ReferenceBuses(Vec<usize>);
16
17impl ReferenceBuses {
18    #[must_use]
19    pub fn new(buses: Vec<usize>) -> Self {
20        Self(buses)
21    }
22
23    pub fn iter(&self) -> std::slice::Iter<'_, usize> {
24        self.0.iter()
25    }
26
27    #[must_use]
28    pub fn len(&self) -> usize {
29        self.0.len()
30    }
31
32    #[must_use]
33    pub fn is_empty(&self) -> bool {
34        self.0.is_empty()
35    }
36
37    /// The one reference bus.
38    ///
39    /// # Errors
40    /// [`powerio::Error::ReferenceBusCount`] unless the set holds exactly one bus.
41    pub fn single(&self) -> Result<usize> {
42        match self.0.as_slice() {
43            [bus] => Ok(*bus),
44            other => Err(powerio::Error::ReferenceBusCount { found: other.len() }.into()),
45        }
46    }
47}
48
49impl AsRef<[usize]> for ReferenceBuses {
50    fn as_ref(&self) -> &[usize] {
51        &self.0
52    }
53}
54
55impl<'a> IntoIterator for &'a ReferenceBuses {
56    type Item = &'a usize;
57    type IntoIter = std::slice::Iter<'a, usize>;
58
59    fn into_iter(self) -> Self::IntoIter {
60        self.0.iter()
61    }
62}