Skip to content

Commit

Permalink
Convert primary keys to serialize_as type
Browse files Browse the repository at this point in the history
  • Loading branch information
Aethelflaed committed Aug 22, 2024
1 parent ae82c4a commit 3dee9a1
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 7 deletions.
26 changes: 19 additions & 7 deletions diesel_derives/src/identifiable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use syn::parse_quote;
use syn::DeriveInput;
use syn::Result;

use crate::attrs::AttributeSpanWrapper;
use crate::field::Field;
use crate::model::Model;
use crate::util::wrap_in_dummy_mod;

Expand All @@ -21,9 +23,19 @@ pub fn derive(item: DeriveInput) -> Result<TokenStream> {
let mut field_ty = Vec::new();
let mut field_name = Vec::new();
for pk in model.primary_key_names.iter() {
let f = model.find_column(pk)?;
field_ty.push(&f.ty);
field_name.push(&f.name);
let Field {
ty,
name,
serialize_as,
..
} = &model.find_column(pk)?;
if let Some(AttributeSpanWrapper { item: ty, .. }) = serialize_as.as_ref() {
field_ty.push(quote!(#ty));
field_name.push(quote!(::std::convert::Into::<#ty>::into(self.#name)));
} else {
field_ty.push(quote!(&'ident #ty));
field_name.push(quote!(&self.#name));
}
}

Ok(wrap_in_dummy_mod(quote! {
Expand All @@ -42,20 +54,20 @@ pub fn derive(item: DeriveInput) -> Result<TokenStream> {
impl #ref_generics Identifiable for &'ident #struct_name #ty_generics
#where_clause
{
type Id = (#(&'ident #field_ty),*);
type Id = (#(#field_ty),*);

fn id(self) -> Self::Id {
(#(&self.#field_name),*)
(#(#field_name),*)
}
}

impl #ref_generics Identifiable for &'_ &'ident #struct_name #ty_generics
#where_clause
{
type Id = (#(&'ident #field_ty),*);
type Id = (#(#field_ty),*);

fn id(self) -> Self::Id {
(#(&self.#field_name),*)
(#(#field_name),*)
}
}
}))
Expand Down
25 changes: 25 additions & 0 deletions diesel_derives/tests/identifiable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,28 @@ fn derive_identifiable_with_composite_pk() {
assert_eq!((&2, &3), foo1.id());
assert_eq!((&6, &7), foo2.id());
}

#[test]
fn derive_identifiable_with_pk_serialize_as() {
#[derive(Debug, PartialEq, Eq, Hash)]
struct MyI32(i32);

impl From<i32> for MyI32 {
fn from(value: i32) -> Self {
MyI32(value)
}
}

#[derive(Identifiable)]
struct Foo {
#[diesel(serialize_as = MyI32)]
id: i32,
#[allow(dead_code)]
foo: i32,
}

let foo1 = Foo { id: 1, foo: 2 };
let foo2 = Foo { id: 2, foo: 3 };
assert_eq!(MyI32(1), foo1.id());
assert_eq!(MyI32(2), foo2.id());
}

0 comments on commit 3dee9a1

Please sign in to comment.