rust_iso20022 0.1.2

ISO 20022 financial message parser and generated Rust types for SWIFT MX XML/JSON.
// @generated by rust_iso20022_codegen 0.1.0; do not edit.
// Source: xsds/schema-manifest.json and the normalized schema descriptor IR.

use std::io::Read;
use std::sync::OnceLock;

use super::{FieldDescriptor, FieldKind, MessageDescriptor};

const DATA: &[u8] = include_bytes!("generated.bin");
static DESCRIPTORS: OnceLock<Box<[MessageDescriptor]>> = OnceLock::new();

pub fn all() -> &'static [MessageDescriptor] {
    DESCRIPTORS.get_or_init(build).as_ref()
}

fn build() -> Box<[MessageDescriptor]> {
    let mut decompressed = Vec::new();
    brotli_decompressor::Decompressor::new(DATA, 4096)
        .read_to_end(&mut decompressed)
        .expect("validated generated metadata compression");
    let data: &'static str = Box::leak(
        String::from_utf8(decompressed)
            .expect("validated generated metadata UTF-8")
            .into_boxed_str(),
    );
    let mut messages = Vec::new();
    let mut current: Option<[&'static str; 10]> = None;
    let mut fields = Vec::new();
    for line in data.lines() {
        let mut columns = line.split('\t');
        match columns.next() {
            Some("M") => {
                finish_message(&mut messages, current.take(), &mut fields);
                current = Some([
                    required(&mut columns),
                    required(&mut columns),
                    required(&mut columns),
                    required(&mut columns),
                    required(&mut columns),
                    required(&mut columns),
                    required(&mut columns),
                    required(&mut columns),
                    required(&mut columns),
                    required(&mut columns),
                ]);
            }
            Some("F") => {
                let logical_path = required(&mut columns);
                let namespace = required(&mut columns);
                let wire_name = required(&mut columns);
                let rust_name = required(&mut columns);
                let type_name = required(&mut columns);
                let min_occurs = required(&mut columns).parse().expect("generated minOccurs");
                let max = required(&mut columns);
                let enum_text = required(&mut columns);
                let documentation = optional(required(&mut columns));
                let choice = required(&mut columns);
                let kind = match required(&mut columns) {
                    "element" => FieldKind::Element,
                    "attribute" => FieldKind::Attribute,
                    "simple_content" => FieldKind::SimpleContent,
                    _ => unreachable!("validated generated field kind"),
                };
                let enum_values = if enum_text.is_empty() {
                    &[][..]
                } else {
                    Box::leak(
                        enum_text
                            .split('\u{1f}')
                            .collect::<Vec<_>>()
                            .into_boxed_slice(),
                    )
                };
                fields.push(FieldDescriptor {
                    logical_path,
                    namespace,
                    wire_name,
                    rust_name,
                    type_name,
                    min_occurs,
                    max_occurs: if max.is_empty() {
                        None
                    } else {
                        Some(max.parse().expect("generated maxOccurs"))
                    },
                    enum_values,
                    documentation,
                    choice_group: if choice.is_empty() {
                        None
                    } else {
                        Some(choice.parse().expect("generated choice group"))
                    },
                    kind,
                });
            }
            _ => unreachable!("validated generated metadata row"),
        }
    }
    finish_message(&mut messages, current, &mut fields);
    messages.into_boxed_slice()
}

fn finish_message(
    messages: &mut Vec<MessageDescriptor>,
    values: Option<[&'static str; 10]>,
    fields: &mut Vec<FieldDescriptor>,
) {
    let Some(values) = values else { return };
    let message_fields = Box::leak(std::mem::take(fields).into_boxed_slice());
    messages.push(MessageDescriptor {
        identity: values[0],
        business_area: values[1],
        namespace: values[2],
        root_element: values[3],
        root_type: values[4],
        description: optional(values[5]),
        schema_path: values[6],
        schema_sha256: values[7],
        generated_module: values[8],
        required_feature: values[9],
        fields: message_fields,
    });
}

fn required(columns: &mut std::str::Split<'static, char>) -> &'static str {
    columns.next().expect("validated generated metadata column")
}

fn optional(value: &'static str) -> Option<&'static str> {
    (!value.is_empty()).then_some(value)
}