Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite #[derive(Queryable)] in derives2 #1529

Merged
merged 1 commit into from
Feb 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions diesel_derives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,13 @@ mod from_sql_row;
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;
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 @@ -28,6 +28,7 @@ mod util;

mod as_changeset;
mod identifiable;
mod queryable;

use diagnostic_shim::*;

Expand All @@ -42,6 +43,11 @@ pub fn derive_identifiable(input: TokenStream) -> TokenStream {
expand_derive(input, identifiable::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
57 changes: 57 additions & 0 deletions diesel_derives2/src/queryable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
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,)*
}
}
}
},
))
}
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 @@ -12,3 +12,4 @@ mod schema;

mod as_changeset;
mod identifiable;
mod queryable;