Skip to main content

structured_asic/
source.rs

1//! One original archive identity and current query for existing LTV mechanisms.
2
3use crate::zip::Archive;
4use structured_asn1::{
5    memory::{Execution, HashWork, MemoryError, Work},
6    range::RangeSource,
7};
8use structured_ltv::source::{Query as QueryTrait, ScopeError, Snapshot};
9
10/// An archive root and its original members have distinct identity kinds.
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
12pub enum Node {
13    /// This actual complete immutable archive, not a selected successful file.
14    Root,
15    /// One original central-directory occurrence, including negative inputs.
16    Member(usize),
17}
18impl HashWork for Node {
19    fn hash_work(&self) -> Result<u64, MemoryError> {
20        Ok(2)
21    }
22}
23
24/// Identity of this actual borrowed original archive/session. Keeping the
25/// archive borrow prevents address reuse from becoming another live document.
26pub struct DocumentId<'v, 's, S: RangeSource>(&'v Archive<'s, S>);
27impl<S: RangeSource> Copy for DocumentId<'_, '_, S> {}
28impl<S: RangeSource> Clone for DocumentId<'_, '_, S> {
29    fn clone(&self) -> Self {
30        *self
31    }
32}
33impl<S: RangeSource> PartialEq for DocumentId<'_, '_, S> {
34    fn eq(&self, other: &Self) -> bool {
35        core::ptr::eq(self.0, other.0)
36    }
37}
38impl<S: RangeSource> Eq for DocumentId<'_, '_, S> {}
39impl<S: RangeSource> core::fmt::Debug for DocumentId<'_, '_, S> {
40    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
41        f.debug_tuple("DocumentId")
42            .field(&core::ptr::from_ref(self.0))
43            .finish()
44    }
45}
46/// Current original/archive admission used by shared material/path/time work.
47/// Node identities distinguish root/member; no logical byte coordinate is
48/// passed off as a physical ZIP span.
49pub struct Query<'q, 'v, 's, S: RangeSource> {
50    archive: &'v Archive<'s, S>,
51    execution: Execution<'q>,
52}
53impl<'s, S: RangeSource> Archive<'s, S> {
54    /// Borrows this actual source with no allocation or account clone.
55    #[must_use]
56    pub fn ltv_query<'q, 'v, W: Work>(&'v self, work: &'q W) -> Query<'q, 'v, 's, S>
57    where
58        'v: 'q,
59    {
60        Query {
61            archive: self,
62            execution: self.session().query(work),
63        }
64    }
65}
66impl<'q, 'v, 's, S: RangeSource> QueryTrait for Query<'q, 'v, 's, S> {
67    type Id = Node;
68    type Document = DocumentId<'v, 's, S>;
69    type Generation = ();
70    type Work = Execution<'q>;
71    fn snapshot(&self) -> Snapshot<Self::Document, ()> {
72        Snapshot {
73            document: DocumentId(self.archive),
74            generation: (),
75        }
76    }
77    fn execution(&self) -> &Self::Work {
78        &self.execution
79    }
80    fn admit(&self, node: Node, units: u64) -> Result<(), ScopeError<Node>> {
81        if !self.archive.unchanged() {
82            return Err(ScopeError::Changed { node });
83        }
84        self.execution
85            .charge_work(units)
86            .map_err(|cause| ScopeError::Resource { node, cause })?;
87        if !self.archive.unchanged() {
88            return Err(ScopeError::Changed { node });
89        }
90        Ok(())
91    }
92}