py-rs-macros 0.1.1

derive macro for py-rs
Documentation
use syn::{Fields, ItemStruct, Result};

use crate::{
    attr::{Attr, StructAttr},
    DerivedPY,
};

mod r#enum;
mod named;
mod newtype;
mod tuple;
mod type_as;
mod type_override;
mod unit;

pub(crate) use r#enum::r#enum_def;

pub(crate) fn struct_def(s: &ItemStruct) -> Result<DerivedPY> {
    let attr = StructAttr::from_attrs(&s.attrs)?;

    type_def(&attr, &s.ident.to_string(), &s.fields)
}

fn type_def(attr: &StructAttr, ident: &str, fields: &Fields) -> Result<DerivedPY> {
    attr.assert_validity(fields)?;

    let name = attr
        .rename
        .clone()
        .unwrap_or_else(|| ident.trim_start_matches("r#").to_owned());
    if let Some(attr_type_override) = &attr.type_override {
        return type_override::type_override_struct(attr, &name, attr_type_override);
    }
    if let Some(attr_type_as) = &attr.type_as {
        return type_as::type_as_struct(attr, &name, attr_type_as);
    }

    match fields {
        Fields::Named(named) => match named.named.len() {
            0 if attr.tag.is_none() => unit::empty_object(attr, &name),
            _ => named::named(attr, &name, named),
        },
        Fields::Unnamed(unnamed) => match unnamed.unnamed.len() {
            0 => unit::empty_array(attr, &name),
            1 => newtype::newtype(attr, &name, unnamed),
            _ => tuple::tuple(attr, &name, unnamed),
        },
        Fields::Unit => unit::null(attr, &name),
    }
}