use std::convert::TryInto;
use crate::circuit::Circuit;
#[derive(Debug)]
pub enum CircuitFilter {
WithMember(String),
}
impl CircuitFilter {
pub fn matches(&self, circuit: &Circuit) -> bool {
match self {
CircuitFilter::WithMember(ref member) if circuit.members().contains(member) => true,
_ => false,
}
}
}
pub trait CircuitStore: Send + Sync + Clone {
fn circuits(&self, filter: Option<CircuitFilter>) -> Result<CircuitIter, CircuitStoreError>;
fn circuit(&self, circuit_name: &str) -> Result<Option<Circuit>, CircuitStoreError>;
}
pub struct CircuitIter {
inner: Box<dyn Iterator<Item = Circuit> + Send>,
total: u64,
}
impl CircuitIter {
pub(crate) fn new(total: u64, inner: Box<dyn Iterator<Item = Circuit> + Send>) -> Self {
Self { inner, total }
}
pub fn total(&self) -> u64 {
self.total
}
}
impl Iterator for CircuitIter {
type Item = Circuit;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
let size = self.total.try_into().unwrap_or(std::usize::MAX);
(size, Some(size))
}
}
#[derive(Debug)]
pub struct CircuitStoreError {
context: String,
source: Option<Box<dyn std::error::Error + Send + 'static>>,
}
impl std::error::Error for CircuitStoreError {}
impl CircuitStoreError {
pub fn new(context: String) -> Self {
Self {
context,
source: None,
}
}
pub fn from_source<T: std::error::Error + Send + 'static>(context: String, source: T) -> Self {
Self {
context,
source: Some(Box::new(source)),
}
}
pub fn context(&self) -> String {
self.context.clone()
}
}
impl std::fmt::Display for CircuitStoreError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
if let Some(ref source) = self.source {
write!(
f,
"CircuitStoreError: Source: {} Context: {}",
source, self.context
)
} else {
write!(f, "CircuitStoreError: Context {}", self.context)
}
}
}