Skip to main content

ooxml_codegen/
lib.rs

1//! Code generator for OOXML types from RELAX NG schemas.
2//!
3//! This crate parses RELAX NG Compact (.rnc) schema files from the ECMA-376
4//! specification and generates Rust structs for Office Open XML types.
5
6pub mod analysis;
7pub mod ast;
8pub mod codegen;
9pub mod lexer;
10pub mod parser;
11pub mod parser_gen;
12pub mod serializer_gen;
13
14pub use analysis::{ModuleReport, analyze_schema};
15pub use ast::{DatatypeParam, Definition, Namespace, Pattern, QName, Schema};
16pub use codegen::{CodegenConfig, FeatureMappings, ModuleMappings, NameMappings, generate};
17pub use lexer::{LexError, Lexer};
18pub use parser::{ParseError, Parser};
19pub use parser_gen::generate_parsers;
20pub use serializer_gen::generate_serializers;
21
22/// Parse an RNC schema from a string.
23pub fn parse_rnc(input: &str) -> Result<Schema, Error> {
24    let tokens = Lexer::new(input).tokenize()?;
25    let schema = Parser::new(tokens).parse()?;
26    Ok(schema)
27}
28
29/// Lex an RNC schema into tokens (for debugging).
30pub fn lex_rnc(input: &str) -> Result<Vec<lexer::Token>, LexError> {
31    Lexer::new(input).tokenize()
32}
33
34#[derive(Debug, thiserror::Error)]
35pub enum Error {
36    #[error("lexer error: {0}")]
37    Lex(#[from] LexError),
38    #[error("parser error: {0}")]
39    Parse(#[from] ParseError),
40}
41
42#[cfg(test)]
43mod tests {
44    use super::*;
45
46    #[test]
47    fn test_parse_simple_schema() {
48        let input = r#"
49namespace w = "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
50
51w_CT_Empty = empty
52w_CT_OnOff = attribute w:val { s_ST_OnOff }?
53w_ST_HighlightColor =
54  string "black"
55  | string "blue"
56  | string "cyan"
57"#;
58        let schema = parse_rnc(input).unwrap();
59        assert_eq!(schema.namespaces.len(), 1);
60        assert_eq!(schema.definitions.len(), 3);
61    }
62}