extruct-macros 0.2.1

Implementation detail of the `extruct` crate. Use https://crates.io/crates/extruct in your code.
Documentation
use crate::extruct_from::Ast;
use syn::{Fields, FieldsNamed, Ident, ItemStruct};

pub(crate) struct Model {
    pub substruct: ItemStruct,
    pub superstruct_name: Ident,
    pub fields: Vec<Ident>,
}

pub(crate) fn analyze(ast: Ast) -> Model {
    let substruct = ast.item;
    let superstruct_name = ast
        .attr
        .require_ident()
        .expect("validated during the parsing stage")
        .to_owned();
    let fields = match substruct.fields {
        Fields::Named(FieldsNamed { ref named, .. }) => named
            .iter()
            .filter_map(|f| f.ident.clone())
            .collect::<Vec<_>>(),
        _ => unreachable!("validated during the parsing stage"),
    };

    Model {
        substruct,
        superstruct_name,
        fields,
    }
}

#[cfg(test)]
mod tests {
    use syn::parse_quote;

    use crate::extruct_from;

    use super::*;

    #[test]
    fn builds_model_from_nonempty_named_struct() {
        let ast = extruct_from::Ast {
            attr: parse_quote!(SuperStruct),
            item: parse_quote!(
                struct NamedStruct {
                    first: u64,
                    second: String,
                    third: Vec<char>,
                }
            ),
        };
        let model = analyze(ast);

        let fields: Vec<_> = ["first", "second", "third"]
            .iter()
            .map(|s| s.to_owned())
            .collect();

        assert_eq!("SuperStruct", model.superstruct_name.to_string());
        assert_eq!("NamedStruct", model.substruct.ident.to_string());
        assert_eq!(
            fields,
            model
                .fields
                .iter()
                .map(|ident| ident.to_string())
                .collect::<Vec<_>>()
        );
    }

    #[test]
    fn builds_model_from_empty_named_struct() {
        let ast = extruct_from::Ast {
            attr: parse_quote!(SuperStruct),
            item: parse_quote!(
                struct NamedStruct {}
            ),
        };
        let model = analyze(ast);

        assert_eq!("SuperStruct", model.superstruct_name.to_string());
        assert_eq!("NamedStruct", model.substruct.ident.to_string());
        assert!(model.fields.is_empty());
    }
}