1use std::fmt;
6
7use crate::{Dom, NamespaceResolver, Node};
8
9pub(crate) struct EvaluationCtx<D: Dom> {
11 pub(crate) starting_node: D::Node,
13 pub(crate) context_node: D::Node,
15 pub(crate) predicate_ctx: Option<PredicateCtx>,
17 pub(crate) resolver: Option<D::NamespaceResolver>,
19}
20
21#[derive(Clone, Copy, Debug)]
22pub(crate) struct PredicateCtx {
23 pub(crate) index: usize,
24 pub(crate) size: usize,
25}
26
27impl<D: Dom> EvaluationCtx<D> {
28 pub(crate) fn new(context_node: D::Node, resolver: Option<D::NamespaceResolver>) -> Self {
30 EvaluationCtx {
31 starting_node: context_node.clone(),
32 context_node,
33 predicate_ctx: None,
34 resolver,
35 }
36 }
37
38 pub(crate) fn subcontext_for_node(&self, node: D::Node) -> Self {
40 EvaluationCtx {
41 starting_node: self.starting_node.clone(),
42 context_node: node,
43 predicate_ctx: self.predicate_ctx,
44 resolver: self.resolver.clone(),
45 }
46 }
47
48 pub(crate) fn resolve_namespace(
50 &self,
51 prefix: Option<&str>,
52 ) -> Result<Option<String>, D::JsError> {
53 if let Some(resolver) = self.resolver.as_ref() {
55 if let Some(namespace_uri) = resolver.resolve_namespace_prefix(prefix)? {
56 return Ok(Some(namespace_uri));
57 }
58 }
59
60 Ok(self.context_node.lookup_namespace_uri(prefix))
62 }
63}
64
65impl<D: Dom> fmt::Debug for EvaluationCtx<D> {
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67 f.debug_struct("EvaluationCtx")
68 .field("starting_node", &self.starting_node)
69 .field("context_node", &self.context_node)
70 .field("predicate_ctx", &self.predicate_ctx)
71 .field("resolver", &"<callback function>")
72 .finish()
73 }
74}