ooxml_codegen/ast.rs
1//! AST types for RELAX NG Compact syntax (subset used by OOXML schemas).
2
3/// A complete RNC schema file.
4#[derive(Debug, Clone)]
5pub struct Schema {
6 pub namespaces: Vec<Namespace>,
7 pub definitions: Vec<Definition>,
8}
9
10/// Namespace declaration: `namespace prefix = "uri"` or `default namespace prefix = "uri"`.
11#[derive(Debug, Clone)]
12pub struct Namespace {
13 pub prefix: String,
14 pub uri: String,
15 pub is_default: bool,
16}
17
18/// A named definition: `name = pattern`.
19#[derive(Debug, Clone)]
20pub struct Definition {
21 pub name: String,
22 pub pattern: Pattern,
23 pub doc_comment: Option<String>,
24}
25
26/// RELAX NG pattern (simplified for OOXML schemas).
27#[derive(Debug, Clone)]
28pub enum Pattern {
29 /// Empty content.
30 Empty,
31 /// Reference to another definition.
32 Ref(String),
33 /// `element name { pattern }`.
34 Element { name: QName, pattern: Box<Pattern> },
35 /// `attribute name { pattern }`.
36 Attribute { name: QName, pattern: Box<Pattern> },
37 /// Sequence: `pattern, pattern`.
38 Sequence(Vec<Pattern>),
39 /// Choice: `pattern | pattern`.
40 Choice(Vec<Pattern>),
41 /// Interleave (unordered): `pattern & pattern`.
42 Interleave(Vec<Pattern>),
43 /// Optional: `pattern?`.
44 Optional(Box<Pattern>),
45 /// Zero or more: `pattern*`.
46 ZeroOrMore(Box<Pattern>),
47 /// One or more: `pattern+`.
48 OneOrMore(Box<Pattern>),
49 /// String literal: `string "value"`.
50 StringLiteral(String),
51 /// XSD datatype: `xsd:integer`, `xsd:string`, etc.
52 Datatype {
53 library: String,
54 name: String,
55 params: Vec<DatatypeParam>,
56 },
57 /// Parenthesized pattern.
58 Group(Box<Pattern>),
59 /// Mixed content: `mixed { pattern }`.
60 Mixed(Box<Pattern>),
61 /// List content: `list { pattern }` (space-separated).
62 List(Box<Pattern>),
63 /// Text content.
64 Text,
65 /// Any content (wildcard pattern).
66 Any,
67}
68
69/// Qualified name with optional prefix.
70#[derive(Debug, Clone)]
71pub struct QName {
72 pub prefix: Option<String>,
73 pub local: String,
74}
75
76/// Name class for element/attribute names (supports wildcards and exclusions).
77#[derive(Debug, Clone)]
78pub enum NameClass {
79 /// A specific qualified name.
80 Name(QName),
81 /// Wildcard: `*` (any name).
82 AnyName,
83 /// Namespace wildcard: `ns:*` (any name in namespace).
84 NsName(String),
85 /// Choice of name classes: `nc1 | nc2`.
86 Choice(Vec<NameClass>),
87 /// Subtraction: `nc1 - nc2` (nc1 except nc2).
88 Except(Box<NameClass>, Box<NameClass>),
89}
90
91/// Datatype parameter: `{ length = "4" }`.
92#[derive(Debug, Clone)]
93pub struct DatatypeParam {
94 pub name: String,
95 pub value: String,
96}
97
98impl Pattern {
99 /// Returns true if this pattern represents a simple type (enum of string literals).
100 pub fn is_simple_type(&self) -> bool {
101 match self {
102 Pattern::Choice(variants) => variants
103 .iter()
104 .all(|v| matches!(v, Pattern::StringLiteral(_))),
105 Pattern::StringLiteral(_) => true,
106 Pattern::Datatype { .. } => true,
107 _ => false,
108 }
109 }
110}