use super::{BasicStage, CredentialMaterial, Timed, X509Material};
use crate::pki::ParticipantError;
use crate::source::Query;
use crate::timestamp::TimestampScope;
pub struct LongTerm<'a, T, M, C> {
timed: &'a T,
x509: &'a M,
credentials: &'a C,
material_complete: bool,
}
impl<T, M, C> LongTerm<'_, T, M, C> {
#[must_use]
pub fn timed(&self) -> &T {
self.timed
}
#[must_use]
pub fn x509(&self) -> &M {
self.x509
}
#[must_use]
pub fn credentials(&self) -> &C {
self.credentials
}
#[must_use]
pub fn all_material_requirements_met(&self) -> bool {
self.material_complete
}
}
pub type MaterialResult<'a, T, M, C, N> = Result<LongTerm<'a, T, M, C>, ParticipantError<N>>;
type TimedOf<'a, 'c, 'd, 'path, 'document, B, Q, I> = Timed<
'a,
'c,
'd,
B,
<B as BasicStage<'path, 'document>>::Signer,
<Q as Query>::Id,
<Q as Query>::Document,
<Q as Query>::Generation,
I,
>;
pub fn long_term<'s, 'a, 'c, 'd, 'path, 'document, B, M, C, Q, I>(
timed: &'s TimedOf<'a, 'c, 'd, 'path, 'document, B, Q, I>,
x509: &'s M,
credentials: &'s C,
query: &Q,
) -> MaterialResult<'s, TimedOf<'a, 'c, 'd, 'path, 'document, B, Q, I>, M, C, Q::Id>
where
'document: 'path,
B: BasicStage<'path, 'document, Id = Q::Id, Document = Q::Document, Generation = Q::Generation>,
M: X509Material<
'path,
'document,
Id = Q::Id,
Document = Q::Document,
Generation = Q::Generation,
Issuer = I,
>,
C: CredentialMaterial<Id = Q::Id, Document = Q::Document, Generation = Q::Generation>,
Q: Query,
{
let requirements = x509.requirements();
if !matches!(requirements.scope(), TimestampScope::All(_))
|| !matches!(credentials.scope(), TimestampScope::All(_))
{
return Err(ParticipantError::Foreign {
signature: requirements.signature(),
});
}
let basic = timed.basic();
requirements.require_inputs(
basic.signer(),
basic.counters(),
credentials.credentials(),
timed.paths(),
query,
)?;
Ok(LongTerm {
timed,
x509,
credentials,
material_complete: x509.all_x509_requirements_met() && credentials.all_requirements_met(),
})
}