use super::{AstNodeId, SourceSpan};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Axis {
Child,
Descendant,
Attribute,
SelfAxis,
DescendantOrSelf,
FollowingSibling,
Following,
Parent,
Ancestor,
PrecedingSibling,
Preceding,
AncestorOrSelf,
Namespace,
}
impl Axis {
pub fn is_reverse(&self) -> bool {
matches!(
self,
Axis::Parent
| Axis::Ancestor
| Axis::PrecedingSibling
| Axis::Preceding
| Axis::AncestorOrSelf
)
}
pub fn is_forward(&self) -> bool {
!self.is_reverse()
}
}
#[derive(Debug, Clone)]
pub enum NodeTest {
Name(NameTest),
Kind(KindTest),
}
#[derive(Debug, Clone)]
pub struct NameTest {
pub prefix: Option<String>,
pub local_name: Option<String>,
}
impl NameTest {
pub fn any() -> Self {
Self {
prefix: None,
local_name: None,
}
}
pub fn any_in_ns(prefix: String) -> Self {
Self {
prefix: Some(prefix),
local_name: None,
}
}
pub fn any_ns(local_name: String) -> Self {
Self {
prefix: None,
local_name: Some(local_name),
}
}
pub fn qname(prefix: String, local_name: String) -> Self {
Self {
prefix: Some(prefix),
local_name: Some(local_name),
}
}
}
#[derive(Debug, Clone)]
pub enum KindTest {
AnyKind,
Text,
Comment,
ProcessingInstruction(Option<String>),
Document(Option<Box<KindTest>>),
Element(ElementTest),
Attribute(AttributeTest),
SchemaElement(String),
SchemaAttribute(String),
}
#[derive(Debug, Clone, Default)]
pub struct ElementTest {
pub name: Option<QName>,
pub type_name: Option<QName>,
pub nillable: bool,
}
#[derive(Debug, Clone, Default)]
pub struct AttributeTest {
pub name: Option<QName>,
pub type_name: Option<QName>,
}
#[derive(Debug, Clone)]
pub struct QName {
pub prefix: String,
pub local: String,
}
impl QName {
pub fn new(prefix: String, local: String) -> Self {
Self { prefix, local }
}
pub fn local_only(local: String) -> Self {
Self {
prefix: String::new(),
local,
}
}
}
#[derive(Debug, Clone)]
pub struct PathStepNode {
pub axis: Axis,
pub test: NodeTest,
pub predicates: Vec<AstNodeId>,
pub span: SourceSpan,
pub resolved_test: Option<crate::types::NameTest>,
}
impl PathStepNode {
pub fn new(axis: Axis, test: NodeTest, span: SourceSpan) -> Self {
Self {
axis,
test,
predicates: Vec::new(),
span,
resolved_test: None,
}
}
pub fn with_predicates(
axis: Axis,
test: NodeTest,
predicates: Vec<AstNodeId>,
span: SourceSpan,
) -> Self {
Self {
axis,
test,
predicates,
span,
resolved_test: None,
}
}
pub fn abbrev_parent(span: SourceSpan) -> Self {
Self {
axis: Axis::Parent,
test: NodeTest::Kind(KindTest::AnyKind),
predicates: Vec::new(),
span,
resolved_test: None,
}
}
}
#[derive(Debug, Clone)]
pub struct PathExprNode {
pub is_absolute: bool,
pub steps: Vec<AstNodeId>,
pub span: SourceSpan,
pub unordered_hint: bool,
}
impl PathExprNode {
pub fn root_only(span: SourceSpan) -> Self {
Self {
is_absolute: true,
steps: Vec::new(),
span,
unordered_hint: false,
}
}
pub fn absolute(steps: Vec<AstNodeId>, span: SourceSpan) -> Self {
Self {
is_absolute: true,
steps,
span,
unordered_hint: false,
}
}
pub fn relative(steps: Vec<AstNodeId>, span: SourceSpan) -> Self {
Self {
is_absolute: false,
steps,
span,
unordered_hint: false,
}
}
}
#[derive(Debug, Clone)]
pub struct FilterExprNode {
pub base: AstNodeId,
pub predicates: Vec<AstNodeId>,
pub span: SourceSpan,
}
impl FilterExprNode {
pub fn new(base: AstNodeId, predicates: Vec<AstNodeId>, span: SourceSpan) -> Self {
Self {
base,
predicates,
span,
}
}
}