structured_xades/timestamp/
coverage.rs1use super::{Input, Part, TimestampXml};
4use crate::xml::{Access, AccessError, Node, Xml};
5use crate::{ISSUER, Xades};
6use structured_asn1::memory::{MemoryError, Work};
7use structured_ltv::material::Coverage;
8
9pub type CoverageFor<X, W> =
14 Coverage<<X as Xml>::Id, <X as Xml>::Document, <X as Xml>::Generation, W, Xades>;
15
16#[derive(Debug)]
18pub enum CoverageError<E, N> {
19 Access(AccessError<E, N>),
21 Resource {
23 node: N,
25 cause: MemoryError,
27 },
28}
29
30type Result<T, X> = core::result::Result<T, CoverageError<<X as Xml>::Error, <X as Xml>::Id>>;
31
32struct Frame<N> {
33 parent: N,
34 next: Option<N>,
35}
36
37impl<X: TimestampXml> Input<'_, X> {
38 pub fn element_coverage<W: Work>(&self, execution: &W) -> Result<CoverageFor<X, W>, X> {
46 let access = Access::new(self.xml, self.snapshot, execution);
47 access
48 .query(self.timestamp, |_, _, _| Ok(()))
49 .map_err(CoverageError::Access)?;
50 let mut elements = execution.map();
51 let mut frames = execution.vector();
52 for ordinal in 0..self.parts.len() {
53 access
54 .query(self.timestamp, |_, _, work| Ok(work.charge_work(1)))
55 .map_err(CoverageError::Access)?
56 .map_err(|cause| CoverageError::Resource {
57 node: self.timestamp,
58 cause,
59 })?;
60 let root = match self.parts[ordinal] {
61 Part::Element(root)
62 | Part::Reference {
63 covered: Some(root),
64 ..
65 } => root,
66 Part::Reference { covered: None, .. } => continue,
67 };
68 let resource = |cause| CoverageError::Resource { node: root, cause };
69 if elements.get(&root, execution).map_err(resource)?.is_some() {
70 continue;
71 }
72 let element = access
76 .inspect(root, |value| matches!(value, Node::Element(_)))
77 .map_err(CoverageError::Access)?;
78 elements.try_insert(root, element).map_err(resource)?;
79 let next = access.first_child(root).map_err(CoverageError::Access)?;
80 frames
81 .try_push(Frame { parent: root, next })
82 .map_err(resource)?;
83 while let Some(frame) = frames.last_mut() {
84 let Some(node) = frame.next else {
85 frames.pop();
86 continue;
87 };
88 frame.next = access
89 .next_sibling(frame.parent, node)
90 .map_err(CoverageError::Access)?;
91 let element = access
92 .inspect(node, |value| matches!(value, Node::Element(_)))
93 .map_err(CoverageError::Access)?;
94 if !element {
95 continue;
96 }
97 if elements.get(&node, execution).map_err(resource)?.is_some() {
98 continue;
99 }
100 elements.try_insert(node, true).map_err(resource)?;
101 let next = access.first_child(node).map_err(CoverageError::Access)?;
102 frames
103 .try_push(Frame { parent: node, next })
104 .map_err(resource)?;
105 }
106 }
107 access
108 .query(self.timestamp, |_, _, _| Ok(()))
109 .map_err(CoverageError::Access)?;
110 Ok(Coverage::new(
111 ISSUER,
112 self.snapshot,
113 self.signature,
114 self.timestamp,
115 self.role.purpose(),
116 elements,
117 ))
118 }
119}