easy_from 0.0.0

Easy macro for deriving From implementations (useful for composing Enums)
Documentation
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, Data, DeriveInput, Fields};

#[proc_macro_derive(EasyFrom, attributes(from))]
pub fn derive_from(stream: TokenStream) -> TokenStream {
	let input = parse_macro_input!(stream as DeriveInput);

	let name = &input.ident;
	let generics = &input.generics;

	let mut out = TokenStream::new();
	match input.data {
		Data::Enum(e) => {
			for v in e.variants.iter() {
				let variant_name = &v.ident;
				match &v.fields {
					Fields::Unnamed(f) => {
						let unnamed = &f.unnamed;
						if unnamed.len() != 1 {
							continue;
						}

						let field = &unnamed[0];
						let attrs = &field.attrs;
						if attrs.len() != 1 {
							continue;
						}

						let attr = &attrs[0];
						let path = &attr.path;
						let segments = &path.segments;
						if segments.len() != 1 {
							continue;
						}

						let segment = &segments[0];
						let ident = &segment.ident;

						if ident != &quote::format_ident!("from") {
							continue;
						}

						let ty = &field.ty;

						out.extend([TokenStream::from(quote! {
							impl #generics core::convert::From<#ty> for #name #generics {
								fn from(t: #ty) -> Self {
									Self::#variant_name(t)
								}
							}
						})]);
					}
					_ => (),
				}
			}
		}
		_ => unimplemented!(),
	}

	out
}