Skip to content

Commit

Permalink
Rewrite #[derive(Queryable)] in derives2
Browse files Browse the repository at this point in the history
This was fairly recently rewritten, so it should in theory be the most
straightforward derive to port. Unfortunately, due to
rust-lang/rust#47311, it's obnoxiously hard to
actually construct a struct in a derive right now. We have to do hacky
workarounds until that is fixed.
  • Loading branch information
sgrif committed Feb 2, 2018
1 parent 0b0b1e8 commit fce0095
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 59 deletions.
6 changes: 0 additions & 6 deletions diesel_derives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,13 @@ mod identifiable;
mod insertable;
mod model;
mod query_id;
mod queryable;
mod queryable_by_name;
mod sql_type;
mod util;

use proc_macro::TokenStream;
use syn::parse_derive_input;

#[proc_macro_derive(Queryable, attributes(column_name))]
pub fn derive_queryable(input: TokenStream) -> TokenStream {
expand_derive(input, queryable::derive_queryable)
}

#[proc_macro_derive(QueryableByName, attributes(table_name, column_name, sql_type, diesel))]
pub fn derive_queryable_by_name(input: TokenStream) -> TokenStream {
expand_derive(input, queryable_by_name::derive)
Expand Down
49 changes: 0 additions & 49 deletions diesel_derives/src/queryable.rs

This file was deleted.

1 change: 0 additions & 1 deletion diesel_derives/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ extern crate diesel;
#[macro_use]
extern crate diesel_derives;

mod queryable;
mod queryable_by_name;
mod associations;
mod test_helpers;
1 change: 1 addition & 0 deletions diesel_derives2/src/as_changeset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ pub fn derive(item: syn::DeriveInput) -> Result<quote::Tokens, Diagnostic> {
model.dummy_mod_name("as_changeset"),
quote!(
use self::diesel::query_builder::AsChangeset;
use self::diesel::prelude::*;

impl #impl_generics AsChangeset for &'update #struct_name #ty_generics
#where_clause
Expand Down
13 changes: 13 additions & 0 deletions diesel_derives2/src/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,19 @@ pub enum FieldName {
Unnamed(syn::Index),
}

impl FieldName {
pub fn for_assignment(&self) -> quote::Tokens {
match *self {
FieldName::Named(mut x) => {
// https://github.com/rust-lang/rust/issues/47311
x.span = Span::call_site();
quote!(#x)
}
FieldName::Unnamed(ref x) => quote!(#x),
}
}
}

impl quote::ToTokens for FieldName {
fn to_tokens(&self, tokens: &mut quote::Tokens) {
use proc_macro2::{Spacing, TokenNode, TokenTree};
Expand Down
6 changes: 6 additions & 0 deletions diesel_derives2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ mod model;
mod util;

mod as_changeset;
mod queryable;

use diagnostic_shim::*;

Expand All @@ -36,6 +37,11 @@ pub fn derive_as_changeset(input: TokenStream) -> TokenStream {
expand_derive(input, as_changeset::derive)
}

#[proc_macro_derive(Queryable, attributes(column_name))]
pub fn derive_queryable(input: TokenStream) -> TokenStream {
expand_derive(input, queryable::derive)
}

fn expand_derive(
input: TokenStream,
f: fn(syn::DeriveInput) -> Result<quote::Tokens, Diagnostic>,
Expand Down
53 changes: 53 additions & 0 deletions diesel_derives2/src/queryable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use proc_macro2::Span;
use quote;
use syn;

use model::*;
use util::*;

pub fn derive(item: syn::DeriveInput) -> Result<quote::Tokens, Diagnostic> {
let model = Model::from_item(&item)?;

let struct_name = item.ident;
let field_ty = model.fields().iter().map(|f| &f.ty).collect::<Vec<_>>();
let field_ty = &field_ty;
let build_expr = model.fields().iter().enumerate().map(|(i, f)| {
let field_name = &f.name.for_assignment();
let i: syn::Index = i.into();
// Make sure `row` has a `def_site` span
let row = quote!(row);
// https://github.com/rust-lang/rust/issues/47311
let span = Span::call_site();
quote_spanned!(span=> #field_name: (#row.#i))
});

let (_, ty_generics, _) = item.generics.split_for_impl();
let mut generics = item.generics.clone();
generics.params.push(parse_quote!(__DB: diesel::backend::Backend));
generics.params.push(parse_quote!(__ST));
{
let where_clause = generics.where_clause.get_or_insert(parse_quote!(where));
where_clause.predicates.push(parse_quote!((#(#field_ty,)*): Queryable<__ST, __DB>));
}
let (impl_generics, _, where_clause) = generics.split_for_impl();

Ok(wrap_in_dummy_mod(
model.dummy_mod_name("queryable"),
quote! {
use self::diesel::Queryable;

impl #impl_generics Queryable<__ST, __DB> for #struct_name #ty_generics
#where_clause
{
type Row = <(#(#field_ty,)*) as Queryable<__ST, __DB>>::Row;

fn build(row: Self::Row) -> Self {
let row: (#(#field_ty,)*) = Queryable::build(row);
Self {
#(#build_expr,)*
}
}
}
},
))
}
1 change: 0 additions & 1 deletion diesel_derives2/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ pub fn wrap_in_dummy_mod(const_name: Ident, item: Tokens) -> Tokens {
mod diesel {
__diesel_use_everything!();
}
use self::diesel::prelude::*;
#item
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use diesel::dsl::sql;
use diesel::*;
use diesel::sql_types::Integer;

use test_helpers::connection;
use helpers::connection;

#[test]
fn named_struct_definition() {
Expand All @@ -20,7 +20,7 @@ fn named_struct_definition() {
#[test]
fn tuple_struct() {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Queryable)]
struct MyStruct(#[column_name(foo)] i32, #[column_name(bar)] i32);
struct MyStruct(#[column_name = "foo"] i32, #[column_name = "bar"] i32);

let conn = connection();
let data = select(sql::<(Integer, Integer)>("1, 2")).get_result(&conn);
Expand Down
1 change: 1 addition & 0 deletions diesel_derives2/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ mod helpers;
mod schema;

mod as_changeset;
mod queryable;

0 comments on commit fce0095

Please sign in to comment.