Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
hoodie committed Dec 23, 2021
1 parent 2371eea commit c1ffa2e
Showing 1 changed file with 33 additions and 36 deletions.
69 changes: 33 additions & 36 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,11 @@ fn impl_with_generator<G: BodyGenerator>(
};

let body = match ast.data {
data @ syn::Data::Struct(ref variant) => {
ref data @ syn::Data::Struct(_) => {
let inner = gen.visit_struct(&data);
quote! { #name #inner }
}
data @ syn::Data::Enum(ref body) => {
ref data @ syn::Data::Enum(ref body) => {
let cases = body.variants.iter().map(|variant| {
let unqualified_ident = &variant.ident;
let ident = quote! { #name::#unqualified_ident };
Expand All @@ -126,28 +126,27 @@ fn impl_with_generator<G: BodyGenerator>(
/// Probably not the best abstraction
trait BodyGenerator {
fn quote_borrowed_params(&self, ast: &syn::DeriveInput) -> Vec<proc_macro2::TokenStream> {
let borrowed_lifetime_params = ast.generics.lifetimes.iter().map(|alpha| quote! { #alpha });
let borrowed_type_params = ast.generics.ty_params.iter().map(|ty| quote! { #ty });
let borrowed_lifetime_params = ast.generics.lifetimes().map(|alpha| quote! { #alpha });
let borrowed_type_params = ast.generics.type_params().map(|ty| quote! { #ty });
borrowed_lifetime_params
.chain(borrowed_type_params)
.collect::<Vec<_>>()
}

fn quote_type_params(&self, ast: &syn::DeriveInput) -> Vec<proc_macro2::TokenStream> {
ast.generics
.lifetimes
.iter()
.lifetimes()
.map(|alpha| quote! { #alpha })
.chain(ast.generics.ty_params.iter().map(|ty| {
.chain(ast.generics.type_params().map(|ty| {
let ident = &ty.ident;
quote! { #ident }
}))
.collect::<Vec<_>>()
}

fn quote_rhs_params(&self, ast: &syn::DeriveInput) -> Vec<proc_macro2::TokenStream> {
let owned_lifetime_params = ast.generics.lifetimes.iter().map(|_| quote! { 'static });
let owned_type_params = ast.generics.ty_params.iter().map(|ty| {
let owned_lifetime_params = ast.generics.lifetimes().map(|_| quote! { 'static });
let owned_type_params = ast.generics.type_params().map(|ty| {
let ident = &ty.ident;
quote! { #ident }
});
Expand Down Expand Up @@ -261,12 +260,8 @@ struct BorrowedGen;

impl BodyGenerator for BorrowedGen {
fn quote_rhs_params(&self, ast: &syn::DeriveInput) -> Vec<proc_macro2::TokenStream> {
let owned_lifetime_params = ast
.generics
.lifetimes
.iter()
.map(|_| quote! { '__borrowedgen });
let owned_type_params = ast.generics.ty_params.iter().map(|ty| {
let owned_lifetime_params = ast.generics.lifetimes().map(|_| quote! { '__borrowedgen });
let owned_type_params = ast.generics.type_params().map(|ty| {
let ident = &ty.ident;
quote! { #ident }
});
Expand Down Expand Up @@ -365,20 +360,22 @@ enum FieldKind {
IterableField(Box<FieldKind>),
JustMoved,
}
fn hack(path: &syn::Path) -> Vec<syn::PathSegment> {
path.segments.iter().cloned().collect::<Vec<_>>()
}

impl FieldKind {
fn resolve(field: &syn::Field) -> Self {
// FIXME: remove this obserdirty
let hack = |path: &syn::Path| path.segments.iter().cloned().collect::<Vec<_>>().as_slice();
match field.ty {
syn::Type::Path(syn::TypePath { ref path, .. }) => {
if is_cow(hack(path)) {
if is_cow(&hack(path)) {
FieldKind::PlainCow
} else if is_cow_alike(hack(path)) {
} else if is_cow_alike(&hack(path)) {
FieldKind::AssumedCow
} else if let Some(kind) = is_opt_cow(hack(path)) {
} else if let Some(kind) = is_opt_cow(&hack(path)) {
kind
} else if let Some(kind) = is_iter_field(hack(path)) {
} else if let Some(kind) = is_iter_field(&hack(path)) {
kind
} else {
FieldKind::JustMoved
Expand Down Expand Up @@ -489,7 +486,7 @@ fn is_opt_cow(mut segments: &[syn::PathSegment]) -> Option<FieldKind> {
loop {
if type_hopefully_is(segments, "std::option::Option") {
if let syn::PathSegment {
parameters: syn::PathParameters::AngleBracketed(ref data),
arguments: syn::PathArguments::AngleBracketed(ref data),
..
} = *segments.last().unwrap()
{
Expand All @@ -499,21 +496,20 @@ fn is_opt_cow(mut segments: &[syn::PathSegment]) -> Option<FieldKind> {
break;
}

if data.types.len() != 1 {
if helpers::number_of_type_arguments(segments) != 1 {
// Option<A, B> probably means some other, movable option
break;
}

match *data.types.first().unwrap() {
syn::Type::Path(
None,
syn::Path {
segments: ref next_segments,
..
},
) => {
//match *data.types.first().unwrap() {
match *data.args.first().unwrap() {
syn::GenericArgument::Type(syn::Type::Path(syn::TypePath {
// segments: ref next_segments,
ref path,
..
})) => {
levels += 1;
segments = next_segments;
segments = &hack(&path.clone());
continue;
}
_ => break,
Expand Down Expand Up @@ -550,12 +546,13 @@ fn is_iter_field(mut segments: &[syn::PathSegment]) -> Option<FieldKind> {
break;
}

match *data.types.first().unwrap() {
syn::Type::Path(syn::TypePath {
segments: ref next_segments,
match &*data.args.first().unwrap() {
syn::GenericArgument::Type(syn::Type::Path(syn::TypePath {
// segments: ref next_segments,
path,
..
}) => {
segments = next_segments;
})) => {
segments = &hack(&path);
continue;
}
_ => break,
Expand Down

0 comments on commit c1ffa2e

Please sign in to comment.