diff --git a/sqlx-macros/src/derives/row.rs b/sqlx-macros/src/derives/row.rs index 60100f6ff1..7466ebd537 100644 --- a/sqlx-macros/src/derives/row.rs +++ b/sqlx-macros/src/derives/row.rs @@ -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 { match &input.data { Data::Struct(DataStruct { @@ -74,7 +76,11 @@ fn expand_derive_from_row_struct( let reads = fields.iter().filter_map(|field| -> Option { 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!( diff --git a/sqlx-macros/src/lib.rs b/sqlx-macros/src/lib.rs index 57fdd13b58..5acd6436f5 100644 --- a/sqlx-macros/src/lib.rs +++ b/sqlx-macros/src/lib.rs @@ -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); diff --git a/tests/postgres-derives.rs b/tests/postgres-derives.rs index 3d630b69da..4538612e79 100644 --- a/tests/postgres-derives.rs +++ b/tests/postgres-derives.rs @@ -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, + + #[sqlx(rename = "struct")] + def_struct: Option, + + name: Option, + } + + let mut conn = new::().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(()) +}