fix: fully qualify types in DeriveValueType macro (#2054)

`DeriveValueType` proc macro relies on several sea-orm types to be
imported. This is partially fixed in #1855 by fully qualifying
`sea_orm::QueryResult`, but others like `sea_orm::Value` is still not
being qualified. Also, if use defined a type alias on
`std::result::Result`, it can cause the proc macro to generate code that
won't compile.

- Fully qualify `sea_orm::Value`, `std::string::String`, and
  `std::result::Result` in `DeriveValueType` proc macro.
- Add some simple integration tests for this.
- Add doc and doc test in `sea_orm_macro::derive_value_type`.
This commit is contained in:
bobogei81123 2024-01-14 07:06:40 -08:00 committed by GitHub
parent e3c94a7708
commit 13d383e43c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 4 deletions

View File

@ -100,7 +100,7 @@ impl DeriveValueType {
quote!( quote!(
#[automatically_derived] #[automatically_derived]
impl std::convert::From<#name> for Value { impl std::convert::From<#name> for sea_orm::Value {
fn from(source: #name) -> Self { fn from(source: #name) -> Self {
source.0.into() source.0.into()
} }
@ -108,18 +108,19 @@ impl DeriveValueType {
#[automatically_derived] #[automatically_derived]
impl sea_orm::TryGetable for #name { impl sea_orm::TryGetable for #name {
fn try_get_by<I: sea_orm::ColIdx>(res: &sea_orm::QueryResult, idx: I) -> Result<Self, sea_orm::TryGetError> { fn try_get_by<I: sea_orm::ColIdx>(res: &sea_orm::QueryResult, idx: I)
-> std::result::Result<Self, sea_orm::TryGetError> {
<#field_type as sea_orm::TryGetable>::try_get_by(res, idx).map(|v| #name(v)) <#field_type as sea_orm::TryGetable>::try_get_by(res, idx).map(|v| #name(v))
} }
} }
#[automatically_derived] #[automatically_derived]
impl sea_orm::sea_query::ValueType for #name { impl sea_orm::sea_query::ValueType for #name {
fn try_from(v: Value) -> Result<Self, sea_orm::sea_query::ValueTypeErr> { fn try_from(v: sea_orm::Value) -> std::result::Result<Self, sea_orm::sea_query::ValueTypeErr> {
<#field_type as sea_orm::sea_query::ValueType>::try_from(v).map(|v| #name(v)) <#field_type as sea_orm::sea_query::ValueType>::try_from(v).map(|v| #name(v))
} }
fn type_name() -> String { fn type_name() -> std::string::String {
stringify!(#name).to_owned() stringify!(#name).to_owned()
} }

View File

@ -838,6 +838,19 @@ pub fn enum_iter(input: TokenStream) -> TokenStream {
.into() .into()
} }
/// Implements traits for types that wrap a database value type.
///
/// This procedure macro implements `From<T> for Value`, `sea_orm::TryGetTable`, and
/// `sea_query::ValueType` for the wrapper type `T`.
///
/// ## Usage
///
/// ```rust
/// use sea_orm::DeriveValueType;
///
/// #[derive(DeriveValueType)]
/// struct MyString(String);
/// ```
#[cfg(feature = "derive")] #[cfg(feature = "derive")]
#[proc_macro_derive(DeriveValueType, attributes(sea_orm))] #[proc_macro_derive(DeriveValueType, attributes(sea_orm))]
pub fn derive_value_type(input: TokenStream) -> TokenStream { pub fn derive_value_type(input: TokenStream) -> TokenStream {

View File

@ -0,0 +1,13 @@
#[test]
fn when_user_import_nothing_macro_still_works_test() {
#[derive(sea_orm::DeriveValueType)]
struct MyString(String);
}
#[test]
fn when_user_alias_result_macro_still_works_test() {
#[allow(dead_code)]
type Result<T> = std::result::Result<T, ()>;
#[derive(sea_orm::DeriveValueType)]
struct MyString(String);
}