Skip to content

Commit 58fdac3

Browse files
authored
fix: include column_name in DeriveColumn FromStr impl (#2603)
* fix: include column_name in DeriveColumn FromStr This updates the `FromStr` implementation in `DeriveColumn` to ensure that `column_name` attributes are recognized. When custom `column_name`s did not match the snake_case or lowerCamelCase variants (that the derivation already provides), then a column Iden could fail to map to a column. * test: ensure Column::from_str recognizes column_name This adds a test case for `DeriveEntityModel` colum names to verify that `Column::from_str` succeeds on a particularly weird `column_name`.
1 parent f7d53a2 commit 58fdac3

File tree

2 files changed

+36
-8
lines changed

2 files changed

+36
-8
lines changed

sea-orm-macros/src/derives/column.rs

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,36 @@ pub fn impl_col_from_str(ident: &Ident, data: &Data) -> syn::Result<TokenStream>
7070
}
7171
};
7272

73-
let columns = data_enum.variants.iter().map(|column| {
74-
let column_iden = column.ident.clone();
75-
let column_str_snake = column_iden.to_string().to_snake_case();
76-
let column_str_mixed = column_iden.to_string().to_lower_camel_case();
77-
quote!(
78-
#column_str_snake | #column_str_mixed => Ok(#ident::#column_iden)
79-
)
80-
});
73+
let columns = data_enum
74+
.variants
75+
.iter()
76+
.map(|column| {
77+
let column_iden = column.ident.clone();
78+
let column_str_snake = column_iden.to_string().to_snake_case();
79+
let column_str_mixed = column_iden.to_string().to_lower_camel_case();
80+
81+
let mut column_name = column_str_snake.clone();
82+
for attr in column.attrs.iter() {
83+
if !attr.path().is_ident("sea_orm") {
84+
continue;
85+
}
86+
attr.parse_nested_meta(|meta| {
87+
if meta.path.is_ident("column_name") {
88+
column_name = meta.value()?.parse::<LitStr>()?.value();
89+
} else {
90+
// Reads the value expression to advance the parse stream.
91+
// Some parameters, such as `primary_key`, do not have any value,
92+
// so ignoring an error occurred here.
93+
let _: Option<Expr> = meta.value().and_then(|v| v.parse()).ok();
94+
}
95+
Ok(())
96+
})?;
97+
}
98+
Ok::<TokenStream, syn::Error>(quote!(
99+
#column_str_snake | #column_str_mixed | #column_name => Ok(#ident::#column_iden)
100+
))
101+
})
102+
.collect::<Result<Vec<_>, _>>()?;
81103

82104
Ok(quote!(
83105
#[automatically_derived]

sea-orm-macros/tests/derive_entity_model_column_name_test.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::str::FromStr;
2+
13
use sea_orm::prelude::*;
24
use sea_orm::Iden;
35
use sea_orm::Iterable;
@@ -36,4 +38,8 @@ fn test_column_names() {
3638
"ordersCount",
3739
]
3840
);
41+
42+
let col =
43+
Column::from_str("lAsTnAmE").expect("column from str should recognize column_name attr");
44+
assert!(matches!(col, Column::LastName))
3945
}

0 commit comments

Comments
 (0)