mirror of
https://github.com/Noratrieb/haesli.git
synced 2026-01-16 12:45:04 +01:00
better parser generation
This commit is contained in:
parent
c43126af1f
commit
83778ac2c9
10 changed files with 859 additions and 516 deletions
|
|
@ -1,7 +1,6 @@
|
|||
mod parser;
|
||||
|
||||
use crate::parser::codegen_parser;
|
||||
use anyhow::Result;
|
||||
use heck::ToUpperCamelCase;
|
||||
use std::fs;
|
||||
use strong_xml::XmlRead;
|
||||
|
|
@ -76,21 +75,21 @@ struct Field {
|
|||
asserts: Vec<Assert>,
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
fn main() {
|
||||
let content = fs::read_to_string("./amqp-0-9-1.xml").unwrap();
|
||||
|
||||
let amqp = Amqp::from_str(&content)?;
|
||||
codegen(&amqp)
|
||||
let amqp = Amqp::from_str(&content).unwrap();
|
||||
codegen(&amqp);
|
||||
}
|
||||
|
||||
fn codegen(amqp: &Amqp) -> Result<()> {
|
||||
fn codegen(amqp: &Amqp) {
|
||||
println!("// This file has been generated by `amqp_codegen`. Do not edit it manually.\n");
|
||||
codegen_domain_defs(amqp)?;
|
||||
codegen_class_defs(amqp)?;
|
||||
codegen_parser(amqp)
|
||||
codegen_domain_defs(amqp);
|
||||
codegen_class_defs(amqp);
|
||||
codegen_parser(amqp);
|
||||
}
|
||||
|
||||
fn codegen_domain_defs(amqp: &Amqp) -> Result<()> {
|
||||
fn codegen_domain_defs(amqp: &Amqp) {
|
||||
for domain in &amqp.domains {
|
||||
let invariants = invariants(domain.asserts.iter());
|
||||
|
||||
|
|
@ -103,11 +102,10 @@ fn codegen_domain_defs(amqp: &Amqp) -> Result<()> {
|
|||
amqp_type_to_rust_type(&domain.kind),
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn codegen_class_defs(amqp: &Amqp) -> Result<()> {
|
||||
fn codegen_class_defs(amqp: &Amqp) {
|
||||
println!("#[derive(Debug, Clone, PartialEq)]");
|
||||
println!("pub enum Class {{");
|
||||
for class in &amqp.classes {
|
||||
let class_name = class.name.to_upper_camel_case();
|
||||
|
|
@ -118,6 +116,7 @@ fn codegen_class_defs(amqp: &Amqp) -> Result<()> {
|
|||
for class in &amqp.classes {
|
||||
let enum_name = class.name.to_upper_camel_case();
|
||||
println!("/// Index {}, handler = {}", class.index, class.handler);
|
||||
println!("#[derive(Debug, Clone, PartialEq)]");
|
||||
println!("pub enum {enum_name} {{");
|
||||
for method in &class.methods {
|
||||
let method_name = method.name.to_upper_camel_case();
|
||||
|
|
@ -127,10 +126,8 @@ fn codegen_class_defs(amqp: &Amqp) -> Result<()> {
|
|||
println!(" {{");
|
||||
for field in &method.fields {
|
||||
let field_name = snake_case(&field.name);
|
||||
let (field_type, field_docs) = resolve_type(
|
||||
field.domain.as_ref().or(field.kind.as_ref()).unwrap(),
|
||||
field.asserts.as_ref(),
|
||||
)?;
|
||||
let (field_type, field_docs) =
|
||||
get_invariants_with_type(field_type(field), field.asserts.as_ref());
|
||||
if !field_docs.is_empty() {
|
||||
println!(" /// {field_docs}");
|
||||
}
|
||||
|
|
@ -143,8 +140,6 @@ fn codegen_class_defs(amqp: &Amqp) -> Result<()> {
|
|||
}
|
||||
println!("}}");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn amqp_type_to_rust_type(amqp_type: &str) -> &'static str {
|
||||
|
|
@ -161,13 +156,25 @@ fn amqp_type_to_rust_type(amqp_type: &str) -> &'static str {
|
|||
}
|
||||
}
|
||||
|
||||
fn field_type(field: &Field) -> &String {
|
||||
field.domain.as_ref().or(field.kind.as_ref()).unwrap()
|
||||
}
|
||||
|
||||
fn resolve_type_from_domain(amqp: &Amqp, domain: &str) -> String {
|
||||
amqp.domains
|
||||
.iter()
|
||||
.find(|d| d.name == domain)
|
||||
.map(|d| d.kind.clone())
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// returns (type name, invariant docs)
|
||||
fn resolve_type(domain: &str, asserts: &[Assert]) -> Result<(String, String)> {
|
||||
fn get_invariants_with_type(domain: &str, asserts: &[Assert]) -> (String, String) {
|
||||
let additional_docs = invariants(asserts.iter());
|
||||
|
||||
let type_name = domain.to_upper_camel_case();
|
||||
|
||||
Ok((type_name, additional_docs))
|
||||
(type_name, additional_docs)
|
||||
}
|
||||
|
||||
fn snake_case(ident: &str) -> String {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue