extruct-macros 0.2.1

Implementation detail of the `extruct` crate. Use https://crates.io/crates/extruct in your code.
Documentation
use proc_macro2::TokenStream;
use syn::{Error, Fields, Item, ItemStruct};

use crate::utils::format_error_output;

pub(crate) type Ast = ItemStruct;

pub(crate) fn parse(input: TokenStream) -> syn::Result<Ast> {
    let item = match syn::parse2::<Item>(input.clone()) {
        Ok(Item::Struct(item)) => Ok(item),
        Ok(_) => {
            // ../tests/fails/fields-doesnt-work-for-enum.rs
            // ../tests/fails/fields-doesnt-work-for-union.rs
            Err(Error::new_spanned(
                &input,
                format_error_output(
                    "item is not a struct",
                    "`#[derive(Fields)]` can only be used on structs",
                ),
            ))
        }
        Err(_) => unreachable!(), // derive macros only apply to structs, enums and unions
    }?;

    if let Fields::Unnamed(ref fields) = item.fields {
        if !fields.unnamed.is_empty() {
            // ../tests/fails/fields-doesnt-work-for-non-empty-tuple-struct.rs
            return Err(Error::new_spanned(
                &input,
                format_error_output("item is a tuple-like struct",
                "`#[derive(Fields)]` can only be used on structs with named fields or unit structs")
            ));
        }
    }

    Ok(item)
}

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

    use super::*;

    #[test]
    fn valid_syntax_struct_named_fields() {
        assert!(parse(quote!(
            struct NamedFields {
                first: u32,
                second: String,
            }
        ))
        .is_ok());
    }

    #[test]
    fn valid_syntax_unit_struct_no_braces() {
        assert!(parse(quote!(
            struct UnitStruct;
        ))
        .is_ok());
    }

    #[test]
    fn valid_syntax_unit_struct_parentheses() {
        assert!(parse(quote!(
            struct UnitStruct();
        ))
        .is_ok());
    }

    #[test]
    fn valid_syntax_unit_struct_curly_braces() {
        assert!(parse(quote!(
            struct UnitStruct {}
        ))
        .is_ok());
    }
}