structured_xades/prepare/
uri.rs1use super::Prepared;
4use crate::reference::LexicalSource;
5use crate::scalar::{Datatype, ScalarXml, UriXml};
6use crate::xml::{Access, AccessError, Xml};
7use crate::{commitment, format, identifier, policy, scalar};
8use structured_asn1::memory::{MemoryError, Work};
9
10#[derive(Debug)]
12pub enum UriError<E, N> {
13 Access(AccessError<E, N>),
15 Structure(crate::properties::Error<E, N>),
17 Identifier(identifier::CheckError<E, N>),
19 Scalar(scalar::Error<E, N>),
21 Policy(policy::SyntaxError<E, N>),
23}
24
25pub type UriResult<X> = Result<(), UriError<<X as Xml>::Error, <X as Xml>::Id>>;
27
28pub fn check_uris<X: ScalarXml + UriXml, W: Work>(
38 prepared: &Prepared<X>,
39 access: &Access<'_, X, W>,
40) -> UriResult<X> {
41 let layout = prepared.bound().containers();
42 let root = layout.signature();
43 if layout.snapshot() != access.snapshot() {
44 return Err(UriError::Access(AccessError::Changed { node: root }));
45 }
46 access
47 .query(root, |_, _, _| Ok(()))
48 .map_err(UriError::Access)?;
49 let mut at = 0;
50 while at < prepared.formats().len() {
51 admit(access, root)?;
52 let original = prepared.formats()[at].original();
53 format::check_encoding(access, original).map_err(UriError::Scalar)?;
54 scalar::check(
55 access,
56 original.node(),
57 LexicalSource::Attribute(crate::xml::Name {
58 namespace: "",
59 local: "ObjectReference",
60 }),
61 Datatype::AnyUri,
62 )
63 .map_err(UriError::Scalar)?;
64 if let Some(node) = original.identifier() {
65 let identifier = identifier::read(access, node).map_err(UriError::Structure)?;
66 identifier::check(access, &identifier).map_err(UriError::Identifier)?;
67 }
68 at += 1;
69 }
70 let mut at = 0;
71 while at < prepared.commitments().len() {
72 admit(access, root)?;
73 let original = prepared.commitments()[at].original();
74 identifier::check(access, original.kind()).map_err(UriError::Identifier)?;
75 if let commitment::Objects::References(nodes) = original.objects() {
76 let mut index = 0;
77 while index < nodes.len() {
78 admit(access, original.node())?;
79 scalar::check(
80 access,
81 nodes[index],
82 LexicalSource::SimpleContent,
83 Datatype::AnyUri,
84 )
85 .map_err(UriError::Scalar)?;
86 index += 1;
87 }
88 }
89 at += 1;
90 }
91 if let Some(original) = prepared.policy() {
92 admit(access, root)?;
93 if let policy::Declaration::Explicit(explicit) = original.declaration() {
94 identifier::check(access, &explicit.identifier).map_err(UriError::Identifier)?;
95 }
96 policy::check_qualifier_syntax(access, original).map_err(UriError::Policy)?;
97 }
98 if let Some(original) = prepared.policy_store() {
99 admit(access, root)?;
100 identifier::check(access, original.specification()).map_err(UriError::Identifier)?;
101 if let policy::StoredDocument::Local(node) = original.document() {
102 scalar::check(access, node, LexicalSource::SimpleContent, Datatype::AnyUri)
103 .map_err(UriError::Scalar)?;
104 }
105 }
106 access
107 .query(root, |_, _, _| Ok(()))
108 .map_err(UriError::Access)
109}
110
111fn admit<X: Xml, W: Work>(access: &Access<'_, X, W>, node: X::Id) -> UriResult<X> {
112 access
113 .execution()
114 .charge_work(1)
115 .map_err(|cause: MemoryError| UriError::Access(AccessError::Resource { node, cause }))
116}