Skip to main content

structured_cms/evidence/
objects.rs

1//! Both literal objects and schema-derived per-algorithm preimages use the
2//! existing `DigestBatch` states and closed finalized-output provenance.
3
4use crate::{
5    digest::{DigestBatch, DigestMemo, PassResult, RequestSource},
6    stream::{AsyncSource, Source},
7};
8use structured_asn1::{digest::Digest, memory::Work};
9
10/// An original object group whose complete streams can suspend for acquisition.
11/// Each batch already contains every requested chain algorithm. Implementations
12/// must return its outputs only after that object's complete successful input.
13pub trait AsyncObjects<'p, P: Digest<'p>> {
14    /// Original acquisition or format-specific comparison failure.
15    type Error;
16    /// Number of original objects, including repeated group occurrences.
17    fn len(&self) -> usize;
18    /// Whether the supplied group has no objects.
19    fn is_empty(&self) -> bool {
20        self.len() == 0
21    }
22    /// Completes this batch for the original object at `index`. The supplied
23    /// work applies to acquisition, validation and the batch's own callbacks.
24    fn run<W: Work>(
25        &mut self,
26        index: usize,
27        batch: DigestBatch<'p, P>,
28        work: &W,
29    ) -> impl core::future::Future<Output = PassResult<DigestMemo<'p, P>, Self::Error, P::Error>>;
30}
31
32/// A borrowed group of literal asynchronous object streams, without allocation.
33pub struct AsyncStreams<'s, S>(pub &'s mut [S]);
34impl<'p, P: Digest<'p>, S: AsyncSource> AsyncObjects<'p, P> for AsyncStreams<'_, S> {
35    type Error = S::Error;
36    fn len(&self) -> usize {
37        self.0.len()
38    }
39    async fn run<W: Work>(
40        &mut self,
41        index: usize,
42        batch: DigestBatch<'p, P>,
43        work: &W,
44    ) -> PassResult<DigestMemo<'p, P>, Self::Error, P::Error> {
45        batch.run_async(&mut self.0[index], work).await
46    }
47}
48
49pub(super) trait Sources<'p, P: Digest<'p>> {
50    type Error;
51    fn len(&self) -> usize;
52    fn run<W: Work>(
53        &mut self,
54        index: usize,
55        batch: DigestBatch<'p, P>,
56        work: &W,
57    ) -> PassResult<DigestMemo<'p, P>, Self::Error, P::Error>;
58}
59pub(super) struct Streams<'s, S>(pub(super) &'s mut [S]);
60impl<'p, P: Digest<'p>, S: Source> Sources<'p, P> for Streams<'_, S> {
61    type Error = S::Error;
62    fn len(&self) -> usize {
63        self.0.len()
64    }
65    fn run<W: Work>(
66        &mut self,
67        index: usize,
68        batch: DigestBatch<'p, P>,
69        work: &W,
70    ) -> PassResult<DigestMemo<'p, P>, Self::Error, P::Error> {
71        batch.run(&mut self.0[index], work)
72    }
73}
74pub(super) struct Requests<'s, S>(pub(super) &'s mut [S]);
75impl<'p, P: Digest<'p>, S: RequestSource<'p, P>> Sources<'p, P> for Requests<'_, S> {
76    type Error = S::Error;
77    fn len(&self) -> usize {
78        self.0.len()
79    }
80    fn run<W: Work>(
81        &mut self,
82        index: usize,
83        batch: DigestBatch<'p, P>,
84        work: &W,
85    ) -> PassResult<DigestMemo<'p, P>, Self::Error, P::Error> {
86        batch.run_requests(&mut self.0[index], work)
87    }
88}