support rename attribute in FromRow macro

This commit is contained in:
sid 2020-04-04 17:48:07 +05:30 committed by Ryan Leckey
parent 543f89d0eb
commit 012c186069
3 changed files with 49 additions and 2 deletions

View File

@ -5,6 +5,8 @@ use syn::{
Fields, FieldsNamed, Lifetime, Stmt,
};
use super::attributes::parse_child_attributes;
pub fn expand_derive_from_row(input: &DeriveInput) -> syn::Result<proc_macro2::TokenStream> {
match &input.data {
Data::Struct(DataStruct {
@ -74,7 +76,11 @@ fn expand_derive_from_row_struct(
let reads = fields.iter().filter_map(|field| -> Option<Stmt> {
let id = &field.ident.as_ref()?;
let id_s = id.to_string().trim_start_matches("r#").to_owned();
let attributes = parse_child_attributes(&field.attrs).unwrap();
let id_s = match attributes.rename {
Some(rename) => rename,
None => id.to_string().trim_start_matches("r#").to_owned(),
};
let ty = &field.ty;
Some(parse_quote!(

View File

@ -190,7 +190,7 @@ pub fn derive_type(tokenstream: TokenStream) -> TokenStream {
}
}
#[proc_macro_derive(FromRow)]
#[proc_macro_derive(FromRow, attributes(sqlx))]
pub fn derive_from_row(input: TokenStream) -> TokenStream {
let input = syn::parse_macro_input!(input as syn::DeriveInput);

View File

@ -183,3 +183,44 @@ async fn test_from_row_with_keyword() -> anyhow::Result<()> {
Ok(())
}
#[cfg(feature = "macros")]
#[cfg_attr(feature = "runtime-async-std", async_std::test)]
#[cfg_attr(feature = "runtime-tokio", tokio::test)]
async fn test_from_row_with_rename() -> anyhow::Result<()> {
use sqlx::prelude::*;
#[derive(Debug, sqlx::FromRow)]
struct AccountKeyword {
#[sqlx(rename = "type")]
own_type: i32,
#[sqlx(rename = "static")]
my_static: String,
#[sqlx(rename = "let")]
custom_let: Option<String>,
#[sqlx(rename = "struct")]
def_struct: Option<String>,
name: Option<String>,
}
let mut conn = new::<Postgres>().await?;
let account: AccountKeyword = sqlx::query_as(
r#"SELECT * from (VALUES (1, 'foo', 'bar', null, null)) accounts(type, static, let, struct, name)"#
)
.fetch_one(&mut conn)
.await?;
println!("{:?}", account);
assert_eq!(1, account.own_type);
assert_eq!("foo", account.my_static);
assert_eq!(None, account.def_struct);
assert_eq!(Some("bar".to_owned()), account.custom_let);
assert_eq!(None, account.name);
Ok(())
}