Skip to content

Commit

Permalink
Add support for generics to #[derive(PeekPoke)]
Browse files Browse the repository at this point in the history
  • Loading branch information
djg committed May 20, 2019
1 parent 5f5612a commit ef7262c
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 6 deletions.
21 changes: 16 additions & 5 deletions peek-poke-derive/src/peek_poke.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use crate::{poke_into_expr, peek_from_expr, max_size_expr};
use crate::{max_size_expr, peek_from_expr, poke_into_expr};
use proc_macro2::TokenStream;
use quote::quote;
use syn::{Data::*, DeriveInput};
use syn::{parse_quote, Data::*, DeriveInput, GenericParam, Generics};

/// Returns `PeekPoke` trait implementation
pub fn get_impl(input: DeriveInput) -> TokenStream {
let name = input.ident;

let generics = add_peek_poke_trait_bound(input.generics);
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
let (max_size, poke_into, peek_from) = match &input.data {
Struct(ref struct_data) => (
max_size_expr::for_struct(&struct_data),
Expand All @@ -25,12 +26,12 @@ pub fn get_impl(input: DeriveInput) -> TokenStream {
#[automatically_derived]
#[allow(unused_qualifications)]
#[allow(unused)]
impl PeekPoke for #name {
impl #impl_generics PeekPoke for #name #ty_generics #where_clause {
#[inline(always)]
fn max_size() -> usize {
#max_size
}

#[inline(always)]
fn poke_into(&self, bytes: *mut u8) -> *mut u8 {
#poke_into
Expand All @@ -43,3 +44,13 @@ pub fn get_impl(input: DeriveInput) -> TokenStream {
}
}
}

// Add a bound `T: PeekPoke` for every type parameter `T`.
fn add_peek_poke_trait_bound(mut generics: Generics) -> Generics {
for param in &mut generics.params {
if let GenericParam::Type(ref mut type_param) = *param {
type_param.bounds.push(parse_quote!(peek_poke::PeekPoke));
}
}
generics
}
14 changes: 13 additions & 1 deletion tests/round_trip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ fn poke_into<V: PeekPoke>(a: &V) -> Vec<u8> {
let end_ptr = a.poke_into(v.as_mut_ptr());
let new_size = end_ptr as usize - v.as_ptr() as usize;
assert!(new_size <= v.capacity());
unsafe { v.set_len(new_size); }
unsafe {
v.set_len(new_size);
}
v
}

Expand Down Expand Up @@ -158,6 +160,16 @@ fn test_phantom_data() {
});
}

#[test]
fn test_generic() {
#[derive(Debug, PartialEq, Eq, PeekPoke)]
struct Foo<T> {
x: T,
y: T,
}
the_same(Foo { x: 19.0, y: 42.0 });
}

#[cfg(feature = "extras")]
mod extra_tests {
use super::*;
Expand Down

0 comments on commit ef7262c

Please sign in to comment.