use super::{Prepared, UriError, check_uris};
use crate::attributes::{self, AttributeXml};
use crate::binary::BinaryXml;
use crate::properties::{self, ClaimedTime, ClaimedTimeBinding, DateTimeXml};
use crate::scalar::{ScalarXml, UriXml};
use crate::xml::{Access, Xml};
use structured_asn1::memory::Work;
pub struct Fields<'prepared, N, D, G> {
prepared: &'prepared super::Preparation<N, D, G>,
claimed_time: ClaimedTime<N, D, G>,
}
impl<N, D, G> Fields<'_, N, D, G> {
#[must_use]
pub fn prepared(&self) -> &super::Preparation<N, D, G> {
self.prepared
}
#[must_use]
pub fn claimed_time(&self) -> &ClaimedTime<N, D, G> {
&self.claimed_time
}
}
#[derive(Debug)]
pub enum FieldError<E, N, D, G> {
Attributes(attributes::Error<E, N>),
Uri(UriError<E, N>),
ValidationReference(crate::validation::ReferenceFieldError<E, N, D, G>),
Time(properties::ClaimedTimeError<E, N>),
UnprovenTime {
node: N,
cause: properties::ClaimedTimeFailure,
},
}
pub type FieldResult<'prepared, X> = Result<
Fields<'prepared, <X as Xml>::Id, <X as Xml>::Document, <X as Xml>::Generation>,
FieldError<<X as Xml>::Error, <X as Xml>::Id, <X as Xml>::Document, <X as Xml>::Generation>,
>;
pub fn check_fields<'prepared, X, W>(
prepared: &'prepared Prepared<X>,
access: &Access<'_, X, W>,
) -> FieldResult<'prepared, X>
where
X: AttributeXml + ScalarXml + UriXml + DateTimeXml + BinaryXml,
W: Work,
{
attributes::check_prepared(prepared, access).map_err(FieldError::Attributes)?;
check_uris(prepared, access).map_err(FieldError::Uri)?;
for index in 0..prepared.validation_references().len() {
access.execution().charge_work(1).map_err(|cause| {
FieldError::ValidationReference(crate::validation::ReferenceFieldError::Resource {
node: prepared.bound().containers().signature(),
cause,
})
})?;
crate::validation::check_reference_fields(&prepared.validation_references()[index], access)
.map_err(FieldError::ValidationReference)?;
}
let claimed_time =
match properties::check_time(prepared.signed(), access).map_err(FieldError::Time)? {
ClaimedTimeBinding::Bound(claimed_time) => claimed_time,
ClaimedTimeBinding::Unproven { node, cause } => {
return Err(FieldError::UnprovenTime { node, cause });
}
};
Ok(Fields {
prepared,
claimed_time,
})
}