fromit 0.1.2

A super powerful macro for generating new structs with getters, setters, and `From` or `TryFrom` implementation based on the given struct.
Documentation
use super::*;

pub(crate) struct FieldLevelSkip {
  pub(crate) default: Option<syn::Path>,
}

impl darling::FromMeta for FieldLevelSkip {
  fn from_meta(item: &syn::Meta) -> darling::Result<Self> {
    match item {
      syn::Meta::Path(_) => Ok(Self { default: None }),
      syn::Meta::List(l) => {
        let mut default: (bool, Option<syn::Path>) = (false, None);
        for item in &l.nested {
          match item {
            syn::NestedMeta::Meta(inner) => {
              if inner.path().is_ident("default") {
                derivit_core::parser::Parser::parse("default", inner, &mut default)?;
              }
            }
            syn::NestedMeta::Lit(v) => {
              return Err(darling::Error::unsupported_format("literal").with_span(v));
            }
          }
        }
        Ok(Self { default: default.1 })
      }
      syn::Meta::NameValue(nv) => {
        Err(darling::Error::unsupported_format("namedValue").with_span(nv))
      }
    }
  }
}

pub(crate) struct ExtraField {
  pub(crate) name: Option<syn::Ident>,
  pub(crate) src_ty: syn::Type,
  pub(crate) src_vis: syn::Visibility,
  pub(crate) vis: Option<syn::Visibility>,
  pub(crate) getter: FieldGetterOptions,
  pub(crate) setter: FieldSetterOptions,
  pub(crate) default: Option<syn::Path>,
  pub(crate) attributes: Attributes,
  pub(crate) named: bool,
}

pub(crate) struct Field {
  pub(crate) src_ty: syn::Type,
  pub(crate) src_vis: syn::Visibility,
  pub(crate) skip: Option<FieldLevelSkip>,
  pub(crate) vis: Option<syn::Visibility>,
  pub(crate) typ: Option<syn::Type>,
  pub(crate) rename: Option<syn::Ident>,
  pub(crate) parent: Option<syn::Ident>,
  pub(crate) getter: FieldGetterOptions,
  pub(crate) setter: FieldSetterOptions,
  pub(crate) from: Option<FieldConverter>,
  pub(crate) into: Option<FieldConverter>,
  pub(crate) attributes: Attributes,
  pub(crate) named: bool,
}

impl Field {
  pub(crate) fn merge(&mut self, other: Self) {
    if other.skip.is_some() {
      self.skip = other.skip;
    }

    if other.vis.is_some() {
      self.vis = other.vis;
    }

    if other.typ.is_some() {
      self.typ = other.typ;
    }

    if other.rename.is_some() {
      self.rename = other.rename;
    }

    if other.parent.is_some() {
      self.parent = other.parent;
    }

    if other.from.is_some() {
      self.from = other.from;
    }

    if other.into.is_some() {
      self.into = other.into;
    }

    self.attributes.attrs.extend(other.attributes.attrs);
  }
}