dtolnay / proc-macro-workshop

Learn to write Rust procedural macros  [Rust Latam conference, Montevideo Uruguay, March 2019]
Apache License 2.0
4.13k stars 1.04k forks source link

Implement custom debug #13

Closed seppo0010 closed 5 years ago

seppo0010 commented 5 years ago

Hi David!

I finally got around to continue with the workshop. Do you mind taking a look at my solution for custom debug? Thanks!

dtolnay commented 5 years ago

Nicely done!

Today I added the rest of the test cases for derive(CustomDebug) that get into more of the difficult cases around trait bounds. Check it out if you're interested: https://github.com/dtolnay/proc-macro-workshop/tree/master/debug/tests

seppo0010 commented 5 years ago

Thanks for the feedback, it looks a lot better now!

seppo0010 commented 5 years ago

I'm pretty sure at this point that there has to be a cleaner way of doing this, @dtolnay, but I'm not sure how to mix this destructuring of structs and arrays... https://github.com/dtolnay/proc-macro-workshop/pull/13/commits/f1f2384614f846b05a1a7854321812796bbe95cd#diff-fd4e0f3362d674b97a10b240e544747cR102

dtolnay commented 5 years ago

You may be able to write the same thing with less indentation and nested closures, like this:

fields
    .named
    .iter()
    .filter_map(|f| {
        let segment = match &f.ty {
            Type::Path(ty) => &ty.path.segments[0],
            _ => return None,
        };
        if segment.ident != "PhantomData" {
            return None;
        }
        let argument = match &segment.arguments {
            PathArguments::AngleBracketed(bracketed) => &bracketed.args[0],
            _ => return None,
        };
        match argument {
            GenericArgument::Type(Type::Path(arg)) => Some(arg.path.segments[0].ident.clone()),
            _ => None,
        }
    })
    .collect()