structured_xades/policy/
syntax.rs1use super::{Declaration, Original, XADES, XADES_141, named, user_notice_with};
4use crate::identifier;
5use crate::properties::Error;
6use crate::reference::LexicalSource;
7use crate::scalar::{self, Datatype, ScalarXml, UriXml};
8use crate::xml::{Access, AccessError, Xml};
9use structured_asn1::memory::Work;
10
11#[derive(Debug)]
13pub enum SyntaxError<E, N> {
14 Structure(Error<E, N>),
16 Scalar(scalar::Error<E, N>),
18 Identifier(identifier::CheckError<E, N>),
20}
21
22impl<E, N> From<Error<E, N>> for SyntaxError<E, N> {
23 fn from(cause: Error<E, N>) -> Self {
24 Self::Structure(cause)
25 }
26}
27
28pub type SyntaxResult<X> = Result<(), SyntaxError<<X as Xml>::Error, <X as Xml>::Id>>;
30
31pub fn check_qualifier_syntax<X: ScalarXml + UriXml, W: Work>(
41 access: &Access<'_, X, W>,
42 reading: &Original<X>,
43) -> SyntaxResult<X> {
44 if reading.snapshot() != access.snapshot() {
45 return Err(Error::Access(AccessError::Changed {
46 node: reading.node(),
47 })
48 .into());
49 }
50 access
51 .query(reading.node(), |_, _, _| Ok(()))
52 .map_err(Error::Access)?;
53 let Declaration::Explicit(explicit) = reading.declaration() else {
54 return Ok(());
55 };
56 let mut index = 0;
57 while index < explicit.qualifiers.len() {
58 access
59 .execution()
60 .charge_work(1)
61 .map_err(|cause| Error::Resource {
62 node: reading.node(),
63 cause,
64 })?;
65 let qualifier = &explicit.qualifiers[index];
66 let mut child = access.first_child(qualifier.node).map_err(Error::Access)?;
67 while let Some(node) = child {
68 if named(access, node, XADES, "SPURI")? {
69 scalar::check(access, node, LexicalSource::SimpleContent, Datatype::AnyUri)
70 .map_err(SyntaxError::Scalar)?;
71 } else if named(access, node, XADES, "SPUserNotice")? {
72 user_notice_with(access, node, |number| {
73 scalar::check(
74 access,
75 number,
76 LexicalSource::SimpleContent,
77 Datatype::Integer,
78 )
79 .map_err(SyntaxError::Scalar)
80 })?;
81 } else if named(access, node, XADES_141, "SPDocSpecification")? {
82 let reading = identifier::read(access, node).map_err(SyntaxError::Structure)?;
83 identifier::check(access, &reading).map_err(SyntaxError::Identifier)?;
84 }
85 child = access
86 .next_sibling(qualifier.node, node)
87 .map_err(Error::Access)?;
88 }
89 index += 1;
90 }
91 access
92 .query(reading.node(), |_, _, _| Ok(()))
93 .map_err(Error::Access)?;
94 Ok(())
95}