kiki 7.0.0

A minimalist parser generator for Rust.
Documentation
#![allow(clippy::useless_conversion)]
// 90% of this boilerplate is generated by
// GitHub Copilot.
// Copilot is not aware of types, so it adds
// useless `.into()` calls.
//
// However, it is not worth the developer's effort
// to manually remove these useless conversions.
// The useless conversions do not slow down runtime speed,
// since the compiler optimizes them away.
// The useless conversions also do
// not harm readability--on the contrary,
// they arguably improve readability.
// Furthermore, if we manually remove the useless conversions now,
// we will have to manually remove them again each time
// we use Copilot to update the code in the future.

use crate::data::{ast, cst};

impl From<cst::File> for ast::File {
    fn from(cst: cst::File) -> Self {
        ast::File {
            items: (*cst.items).into(),
        }
    }
}

impl From<cst::OptItems> for Vec<ast::FileItem> {
    fn from(cst: cst::OptItems) -> Self {
        match cst {
            cst::OptItems::Nil => vec![],
            cst::OptItems::Cons(left, right) => {
                let mut items: Vec<ast::FileItem> = (*left).into();
                items.push((*right).into());
                items
            }
        }
    }
}

impl From<cst::FileItem> for ast::FileItem {
    fn from(cst: cst::FileItem) -> Self {
        match cst {
            cst::FileItem::Start(ident) => ast::FileItem::Start(ident.into()),
            cst::FileItem::Struct(struct_) => ast::FileItem::Struct((*struct_).into()),
            cst::FileItem::Enum(enum_) => ast::FileItem::Enum((*enum_).into()),
            cst::FileItem::Terminal(terminal) => ast::FileItem::Terminal((*terminal).into()),
        }
    }
}

impl From<cst::Struct> for ast::Struct {
    fn from(cst: cst::Struct) -> Self {
        ast::Struct {
            attributes: (*cst.attributes).into(),
            name: cst.name.into(),
            fieldset: (*cst.fieldset).into(),
        }
    }
}

impl From<cst::Enum> for ast::Enum {
    fn from(cst: cst::Enum) -> Self {
        ast::Enum {
            attributes: (*cst.attributes).into(),
            name: cst.name.into(),
            variants: (*cst.variants).into(),
        }
    }
}

impl From<cst::TerminalEnum> for ast::TerminalEnum {
    fn from(cst: cst::TerminalEnum) -> Self {
        ast::TerminalEnum {
            attributes: (*cst.attributes).into(),
            name: cst.name.into(),
            variants: (*cst.variants).into(),
        }
    }
}

impl From<cst::OptOuterAttributes> for Vec<ast::Attribute> {
    fn from(cst: cst::OptOuterAttributes) -> Self {
        match cst {
            cst::OptOuterAttributes::Nil => vec![],
            cst::OptOuterAttributes::Cons(left, right) => {
                let mut attributes: Vec<ast::Attribute> = (*left).into();
                attributes.push(right);
                attributes
            }
        }
    }
}

impl From<cst::Fieldset> for ast::Fieldset {
    fn from(cst: cst::Fieldset) -> Self {
        match cst {
            cst::Fieldset::Empty => ast::Fieldset::Empty,
            cst::Fieldset::Named(named_fieldset) => ast::Fieldset::Named((*named_fieldset).into()),
            cst::Fieldset::Tuple(tuple_fieldset) => ast::Fieldset::Tuple((*tuple_fieldset).into()),
        }
    }
}

impl From<cst::NamedFieldset> for ast::NamedFieldset {
    fn from(cst: cst::NamedFieldset) -> Self {
        ast::NamedFieldset {
            fields: (*cst.fields).into(),
        }
    }
}

impl From<cst::NamedFields> for Vec<ast::NamedField> {
    fn from(cst: cst::NamedFields) -> Self {
        match cst {
            cst::NamedFields::One(named_field) => vec![(*named_field).into()],
            cst::NamedFields::Cons(left, right) => {
                let mut fields: Vec<ast::NamedField> = (*left).into();
                fields.push((*right).into());
                fields
            }
        }
    }
}

impl From<cst::NamedField> for ast::NamedField {
    fn from(cst: cst::NamedField) -> Self {
        ast::NamedField {
            name: (*cst.name).into(),
            symbol: (*cst.symbol).into(),
        }
    }
}

impl From<cst::TupleFieldset> for ast::TupleFieldset {
    fn from(cst: cst::TupleFieldset) -> Self {
        ast::TupleFieldset {
            fields: (*cst.fields).into(),
        }
    }
}

impl From<cst::TupleFields> for Vec<ast::TupleField> {
    fn from(cst: cst::TupleFields) -> Self {
        match cst {
            cst::TupleFields::One(field) => vec![(*field).into()],
            cst::TupleFields::Cons(left, right) => {
                let mut fields: Vec<ast::TupleField> = (*left).into();
                fields.push((*right).into());
                fields
            }
        }
    }
}

impl From<cst::TupleField> for ast::TupleField {
    fn from(cst: cst::TupleField) -> Self {
        match cst {
            cst::TupleField::Skipped(named_field) => {
                ast::TupleField::Skipped((*named_field).into())
            }
            cst::TupleField::Used(symbol) => ast::TupleField::Used((*symbol).into()),
        }
    }
}

impl From<cst::OptEnumVariants> for Vec<ast::EnumVariant> {
    fn from(cst: cst::OptEnumVariants) -> Self {
        match cst {
            cst::OptEnumVariants::Nil => vec![],
            cst::OptEnumVariants::Cons(left, right) => {
                let mut variants: Vec<ast::EnumVariant> = (*left).into();
                variants.push((*right).into());
                variants
            }
        }
    }
}

impl From<cst::EnumVariant> for ast::EnumVariant {
    fn from(cst: cst::EnumVariant) -> Self {
        ast::EnumVariant {
            name: cst.name.into(),
            fieldset: (*cst.fieldset).into(),
        }
    }
}

impl From<cst::OptTerminalEnumVariants> for Vec<ast::TerminalEnumVariant> {
    fn from(cst: cst::OptTerminalEnumVariants) -> Self {
        match cst {
            cst::OptTerminalEnumVariants::Nil => vec![],
            cst::OptTerminalEnumVariants::Cons(left, right) => {
                let mut variants: Vec<ast::TerminalEnumVariant> = (*left).into();
                variants.push((*right).into());
                variants
            }
        }
    }
}

impl From<cst::TerminalEnumVariant> for ast::TerminalEnumVariant {
    fn from(cst: cst::TerminalEnumVariant) -> Self {
        ast::TerminalEnumVariant {
            name: cst.name.into(),
            type_: (*cst.type_).into(),
        }
    }
}

impl From<cst::Type> for ast::Type {
    fn from(cst: cst::Type) -> Self {
        match cst {
            cst::Type::Unit => ast::Type::Unit,
            cst::Type::Path(path) => ast::Type::Path((*path).into()),
            cst::Type::Complex(complex_type) => {
                ast::Type::Complex(Box::new((*complex_type).into()))
            }
        }
    }
}

impl From<cst::Path> for Vec<ast::Ident> {
    fn from(cst: cst::Path) -> Self {
        match cst {
            cst::Path::One(ident) => vec![ident.into()],
            cst::Path::Cons(left, right) => {
                let mut left: Vec<ast::Ident> = (*left).into();
                left.push(right.into());
                left
            }
        }
    }
}

impl From<cst::ComplexType> for ast::ComplexType {
    fn from(cst: cst::ComplexType) -> Self {
        ast::ComplexType {
            callee: (*cst.callee).into(),
            args: (*cst.args).into(),
        }
    }
}

impl From<cst::CommaSeparatedTypes> for Vec<ast::Type> {
    fn from(cst: cst::CommaSeparatedTypes) -> Self {
        match cst {
            cst::CommaSeparatedTypes::One(type_) => vec![(*type_).into()],
            cst::CommaSeparatedTypes::Cons(left, right) => {
                let mut types: Vec<ast::Type> = (*left).into();
                types.push((*right).into());
                types
            }
        }
    }
}