use std::fmt;
use std::time::SystemTime;
use crate::{
RevocationStatus,
cert::{
Cert,
components::{
ComponentBundle,
ComponentBundleIter,
Amalgamation,
ComponentAmalgamation,
ValidComponentAmalgamation,
},
},
policy::Policy,
};
pub struct ComponentIter<'a, C> {
cert: &'a Cert,
iter: ComponentBundleIter<'a, C>,
}
impl<'a, C> fmt::Debug for ComponentIter<'a, C> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("ComponentIter")
.finish()
}
}
impl<'a, C> Iterator for ComponentIter<'a, C> {
type Item = ComponentAmalgamation<'a, C>;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|c| ComponentAmalgamation::new(self.cert, c))
}
}
impl<'a, C> ComponentIter<'a, C> {
pub(crate) fn new(cert: &'a Cert,
iter: std::slice::Iter<'a, ComponentBundle<C>>) -> Self
where Self: 'a
{
ComponentIter {
cert, iter: ComponentBundleIter { iter: Some(iter), },
}
}
pub fn with_policy<T>(self, policy: &'a dyn Policy, time: T)
-> ValidComponentIter<'a, C>
where T: Into<Option<SystemTime>>
{
ValidComponentIter {
cert: self.cert,
iter: self.iter,
time: time.into().unwrap_or_else(SystemTime::now),
policy: policy,
revoked: None,
}
}
pub fn bundles(self) -> ComponentBundleIter<'a, C> {
self.iter
}
}
pub struct ValidComponentIter<'a, C> {
cert: &'a Cert,
iter: ComponentBundleIter<'a, C>,
policy: &'a dyn Policy,
time: SystemTime,
revoked: Option<bool>,
}
impl<'a, C> fmt::Debug for ValidComponentIter<'a, C> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("ValidComponentIter")
.field("time", &self.time)
.field("revoked", &self.revoked)
.finish()
}
}
impl<'a, C> Iterator for ValidComponentIter<'a, C>
where C: std::fmt::Debug
{
type Item = ValidComponentAmalgamation<'a, C>;
fn next(&mut self) -> Option<Self::Item> {
tracer!(false, "ValidComponentIter::next", 0);
t!("ValidComponentIter: {:?}", self);
loop {
let ca = ComponentAmalgamation::new(self.cert, self.iter.next()?);
t!("Considering component: {:?}", ca.bundle());
let vca
= if let Ok(vca) = ca.with_policy(self.policy, self.time) {
vca
} else {
t!("No self-signature at time {:?}", self.time);
continue;
};
if let Some(want_revoked) = self.revoked {
if let RevocationStatus::Revoked(_) = vca.revoked() {
if ! want_revoked {
t!("Component revoked... skipping.");
continue;
}
} else {
if want_revoked {
t!("Component not revoked... skipping.");
continue;
}
}
}
return Some(vca);
}
}
}
impl<'a, C> ExactSizeIterator for ComponentIter<'a, C> {
fn len(&self) -> usize {
self.iter.len()
}
}
impl<'a, C> ValidComponentIter<'a, C> {
pub fn revoked<T>(mut self, revoked: T) -> Self
where T: Into<Option<bool>>
{
self.revoked = revoked.into();
self
}
}