lib-ruby-parser 3.0.11

Ruby parser
Documentation
use lib_ruby_parser_nodes::{template::*, Message, MessageField};

const TEMPLATE: &str = "// This file is auto-generated by {{ helper generated-by }}

use crate::DiagnosticMessage;
use crate::blobs::Blob;
use crate::containers::ExternalStringPtr as StringPtr;

{{ each message }}<dnl>
/// External {{ helper message-camelcase-name }}
#[repr(C)]
pub struct {{ helper message-camelcase-name }} {
    pub(crate) blob: Blob<Self>,
}

extern \"C\" {
    fn {{ helper extern-variant-getter-name }}(blob: *const Blob<DiagnosticMessage>) -> *const Blob<{{ helper message-camelcase-name }}>;
{{ each message-field }}<dnl>
    fn {{ helper extern-field-getter-name }}(blob: *const Blob<{{ helper message-camelcase-name }}>) -> *const Blob<{{ helper message-field-rust-field-type }}>;
{{ end }}<dnl>
}

impl {{ helper message-camelcase-name }} {
{{ each message-field }}<dnl>
    /// Returns `{{ helper message-field-name }}` field
    pub fn get_{{ helper message-field-name }}(&self) -> &{{ helper message-field-rust-field-type }} {
        unsafe {
            #[allow(trivial_casts)]
            ({{ helper extern-field-getter-name }}(&self.blob) as *const {{ helper message-field-rust-field-type }}).as_ref().unwrap()
        }
    }
{{ end }}<dnl>
}

impl std::fmt::Debug for {{ helper message-camelcase-name }} {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct(\"{{ helper message-camelcase-name }}\")
{{ each message-field }}<dnl>
            .field(\"{{ helper message-field-name }}\", self.get_{{ helper message-field-name }}())
{{ end }}<dnl>
            .finish()
    }
}

impl PartialEq for {{ helper message-camelcase-name }} {
    #[allow(unused_variables)]
    fn eq(&self, other: &Self) -> bool {
{{ if message-has-no-fields }}<dnl>
        true
{{ else }}<dnl>
{{ each message-field }}<dnl>
        if self.get_{{ helper message-field-name }}() != other.get_{{ helper message-field-name }}() {
            return false
        }
{{ end }}<dnl>
        true
{{ end }}<dnl>
    }
}

impl DiagnosticMessage {
    /// Casts `self` to `Option<&{{ helper message-camelcase-name }}>`, return `None` if variant doesn't match
    pub fn as_{{ helper message-lower-name }}(&self) -> Option<&{{ helper message-camelcase-name }}> {
        unsafe {
            ({{ helper extern-variant-getter-name }}(&self.blob) as *const {{ helper message-camelcase-name }}).as_ref()
        }
    }
}

{{ end }}<dnl>


";

pub(crate) fn codegen() {
    let template = TemplateRoot::new(TEMPLATE).unwrap();
    let mut fns = crate::codegen::fns::default_fns!();

    fns.register::<Message, F::Helper>(
        "extern-variant-getter-name",
        lib_ruby_parser_bindings::helpers::messages::variant_getter::name,
    );
    fns.register::<MessageField, F::Helper>(
        "extern-field-getter-name",
        lib_ruby_parser_bindings::helpers::messages::field_getter::name,
    );

    let contents = template.render(ALL_DATA, &fns);
    std::fs::write("src/error/message/external/variants.rs", contents).unwrap();
}