pub use failure::Fail;
#[derive(Clone, Debug, PartialEq)]
pub struct Fault<N, F: Fail> {
pub node_id: N,
pub kind: F,
}
impl<N, F> Fault<N, F>
where
F: Fail,
{
pub fn new(node_id: N, kind: F) -> Self {
Fault { node_id, kind }
}
pub fn map<F2, FF>(self, f_fault: FF) -> Fault<N, F2>
where
F2: Fail,
FF: Fn(F) -> F2,
{
Fault {
node_id: self.node_id,
kind: f_fault(self.kind),
}
}
}
impl<N, F> Into<FaultLog<N, F>> for Fault<N, F>
where
F: Fail,
{
fn into(self) -> FaultLog<N, F> {
FaultLog(vec![self])
}
}
#[derive(Debug, PartialEq)]
pub struct FaultLog<N, F: Fail>(pub Vec<Fault<N, F>>);
impl<N, F> FaultLog<N, F>
where
F: Fail,
{
pub fn new() -> Self {
FaultLog::default()
}
pub fn init(node_id: N, kind: F) -> Self {
Fault::new(node_id, kind).into()
}
pub fn append(&mut self, node_id: N, kind: F) {
self.0.push(Fault::new(node_id, kind));
}
pub fn append_fault(&mut self, fault: Fault<N, F>) {
self.0.push(fault);
}
pub fn extend(&mut self, new_logs: FaultLog<N, F>) {
self.0.extend(new_logs.0);
}
pub fn merge_into(self, logs: &mut FaultLog<N, F>) {
logs.extend(self);
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn map<F2, FF>(self, f_fault: FF) -> FaultLog<N, F2>
where
F2: Fail,
FF: Fn(F) -> F2,
{
FaultLog(self.into_iter().map(|f| f.map(&f_fault)).collect())
}
}
impl<N, F> Default for FaultLog<N, F>
where
F: Fail,
{
fn default() -> Self {
FaultLog(vec![])
}
}
impl<N, F> IntoIterator for FaultLog<N, F>
where
F: Fail,
{
type Item = Fault<N, F>;
type IntoIter = std::vec::IntoIter<Fault<N, F>>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl<N, F> std::iter::FromIterator<Fault<N, F>> for FaultLog<N, F>
where
F: Fail,
{
fn from_iter<I: IntoIterator<Item = Fault<N, F>>>(iter: I) -> Self {
let mut log = FaultLog::new();
for i in iter {
log.append_fault(i);
}
log
}
}