use std::slice;
use std::fmt;
use std::time::SystemTime;
use crate::{
types::RevocationStatus,
cert::prelude::*,
packet::{
Unknown,
UserAttribute,
UserID,
},
policy::Policy,
};
pub struct ComponentAmalgamationIter<'a, C> {
cert: &'a Cert,
iter: slice::Iter<'a, ComponentBundle<C>>,
}
assert_send_and_sync!(ComponentAmalgamationIter<'_, C> where C);
pub type UserIDAmalgamationIter<'a>
= ComponentAmalgamationIter<'a, UserID>;
pub type UserAttributeAmalgamationIter<'a>
= ComponentAmalgamationIter<'a, UserAttribute>;
pub type UnknownComponentAmalgamationIter<'a>
= ComponentAmalgamationIter<'a, Unknown>;
impl<'a, C> fmt::Debug for ComponentAmalgamationIter<'a, C> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("ComponentAmalgamationIter")
.finish()
}
}
impl<'a, C> Iterator for ComponentAmalgamationIter<'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> ComponentAmalgamationIter<'a, C> {
pub(crate) fn new(cert: &'a Cert,
iter: std::slice::Iter<'a, ComponentBundle<C>>) -> Self
where Self: 'a
{
ComponentAmalgamationIter {
cert, iter,
}
}
pub fn with_policy<T>(self, policy: &'a dyn Policy, time: T)
-> ValidComponentAmalgamationIter<'a, C>
where T: Into<Option<SystemTime>>
{
ValidComponentAmalgamationIter {
cert: self.cert,
iter: self.iter,
time: time.into().unwrap_or_else(crate::now),
policy,
revoked: None,
}
}
}
pub struct ValidComponentAmalgamationIter<'a, C> {
cert: &'a Cert,
iter: slice::Iter<'a, ComponentBundle<C>>,
policy: &'a dyn Policy,
time: SystemTime,
revoked: Option<bool>,
}
assert_send_and_sync!(ValidComponentAmalgamationIter<'_, C> where C);
pub type ValidUserIDAmalgamationIter<'a>
= ValidComponentAmalgamationIter<'a, UserID>;
pub type ValidUserAttributeAmalgamationIter<'a>
= ValidComponentAmalgamationIter<'a, UserAttribute>;
impl<'a, C> fmt::Debug for ValidComponentAmalgamationIter<'a, C> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("ValidComponentAmalgamationIter")
.field("time", &self.time)
.field("revoked", &self.revoked)
.finish()
}
}
impl<'a, C> Iterator for ValidComponentAmalgamationIter<'a, C>
where
C: std::fmt::Debug + Send + Sync,
{
type Item = ValidComponentAmalgamation<'a, C>;
fn next(&mut self) -> Option<Self::Item> {
tracer!(false, "ValidComponentAmalgamationIter::next", 0);
t!("ValidComponentAmalgamationIter: {:?}", self);
loop {
let ca = ComponentAmalgamation::new(self.cert, self.iter.next()?);
t!("Considering component: {:?}", ca.component());
let vca = match ca.with_policy(self.policy, self.time) {
Ok(vca) => vca,
Err(e) => {
t!("Rejected: {}", e);
continue;
},
};
if let Some(want_revoked) = self.revoked {
if let RevocationStatus::Revoked(_) = vca.revocation_status() {
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 ComponentAmalgamationIter<'a, C>
{
fn len(&self) -> usize {
self.iter.len()
}
}
impl<'a, C> ValidComponentAmalgamationIter<'a, C> {
pub fn revoked<T>(mut self, revoked: T) -> Self
where T: Into<Option<bool>>
{
self.revoked = revoked.into();
self
}
}