lib-ruby-parser 3.0.5

Ruby parser
Documentation
use super::comment::Comment;

pub(crate) struct Messages<'a> {
    registry: &'a lib_ruby_parser_nodes::Messages,
}

impl<'a> Messages<'a> {
    pub(crate) fn new(registry: &'a lib_ruby_parser_nodes::Messages) -> Self {
        Self { registry }
    }

    pub(crate) fn write(&self) {
        std::fs::write("src/error/message_gen.rs", self.contents()).unwrap();
    }

    fn contents(&self) -> String {
        format!(
            "#[cfg(feature = \"compile-with-external-structures\")]
use crate::containers::ExternalStringPtr;
#[cfg(feature = \"compile-with-external-structures\")]
type StringPtr = ExternalStringPtr;
#[cfg(not(feature = \"compile-with-external-structures\"))]
type StringPtr = String;

/// Enum of all possible diagnostic message (both warnings and errors)
#[derive(Debug, Clone, PartialEq, Eq)]
#[repr(C)]
pub enum DiagnosticMessage {{
    {sections}
}}
",
            sections = self.sections().join("\n    ")
        )
    }

    fn sections(&self) -> Vec<String> {
        self.registry
            .sections
            .iter()
            .map(|s| Section::new(s).to_string())
            .collect()
    }
}

struct Section<'a> {
    section: &'a lib_ruby_parser_nodes::Section,
}

impl<'a> Section<'a> {
    fn new(section: &'a lib_ruby_parser_nodes::Section) -> Self {
        Self { section }
    }

    fn to_string(&self) -> String {
        format!(
            "/* {section_name} */

{messages}",
            section_name = self.section.name,
            messages = self.messages().join("\n\n")
        )
    }

    fn messages(&self) -> Vec<String> {
        self.section
            .messages
            .iter()
            .map(|m| Message::new(m).to_string())
            .collect()
    }
}

struct Message<'a> {
    message: &'a lib_ruby_parser_nodes::Message,
}

impl<'a> Message<'a> {
    fn new(message: &'a lib_ruby_parser_nodes::Message) -> Self {
        Self { message }
    }

    fn to_string(&self) -> String {
        format!(
            "{comment}
    {variant}{fields},",
            comment = Comment::new(&self.message.comment).to_string(4),
            variant = self.message.name,
            fields = self.fields()
        )
    }

    fn fields(&self) -> String {
        if self.message.fields.is_empty() {
            return "".to_string();
        }

        let fields = self
            .message
            .fields
            .iter()
            .map(|f| Field::new(f).to_string())
            .collect::<Vec<_>>();

        format!(
            " {{
{}
    }}",
            fields.join("\n\n")
        )
    }
}

struct Field<'a> {
    field: &'a lib_ruby_parser_nodes::MessageField,
}

impl<'a> Field<'a> {
    fn new(field: &'a lib_ruby_parser_nodes::MessageField) -> Self {
        Self { field }
    }

    fn to_string(&self) -> String {
        format!(
            "{comment}
        {field_name}: {field_type},",
            comment = Comment::new(&self.field.comment).to_string(8),
            field_name = self.field.name,
            field_type = self.field_type(),
        )
    }

    fn field_type(&self) -> &str {
        use lib_ruby_parser_nodes::MessageFieldType as FieldType;

        match self.field.field_type {
            FieldType::Str => "StringPtr",
            FieldType::Byte => "u8",
        }
    }
}