From 13d7a265f03f3f675fe65a7f2b9ea916e0440657 Mon Sep 17 00:00:00 2001 From: owjs3901 Date: Thu, 2 Apr 2026 04:55:05 +0900 Subject: [PATCH] fix: use split_whitespace() instead of replace(' ') in proc macros to handle newlines in long type paths --- sea-orm-macros/src/derives/active_model_ex.rs | 15 +++++++++------ sea-orm-macros/src/derives/arrow_schema.rs | 10 ++++++++-- sea-orm-macros/src/derives/entity_model.rs | 5 +++-- sea-orm-macros/src/derives/model_ex.rs | 10 ++++++---- sea-orm-macros/src/derives/typed_column.rs | 5 +++-- sea-orm-macros/src/derives/util.rs | 5 +++-- sea-orm-macros/src/derives/value_type.rs | 5 +++-- 7 files changed, 35 insertions(+), 20 deletions(-) diff --git a/sea-orm-macros/src/derives/active_model_ex.rs b/sea-orm-macros/src/derives/active_model_ex.rs index 7e6d48b491..cd2eae6739 100644 --- a/sea-orm-macros/src/derives/active_model_ex.rs +++ b/sea-orm-macros/src/derives/active_model_ex.rs @@ -50,9 +50,10 @@ pub fn expand_derive_active_model_ex( for field in fields.named.iter() { if field.ident.is_some() && field_not_ignored_compound(field) { let field_type = &field.ty; - let field_type = quote! { #field_type } + let field_type: String = quote! { #field_type } .to_string() // e.g.: "Option < String >" - .replace(' ', ""); // Remove spaces + .split_whitespace() + .collect(); // Remove all whitespace if is_compound_field(&field_type) { let entity_path = extract_compound_entity(&field_type); @@ -69,9 +70,10 @@ pub fn expand_derive_active_model_ex( if let Some(ident) = &field.ident { if field_not_ignored_compound(field) { let field_type = &field.ty; - let field_type = quote! { #field_type } + let field_type: String = quote! { #field_type } .to_string() // e.g.: "Option < String >" - .replace(' ', ""); // Remove spaces + .split_whitespace() + .collect(); // Remove all whitespace let ty = if is_compound_field(&field_type) { compound_fields.push(ident); @@ -706,9 +708,10 @@ fn expand_active_model_setters(data: &Data) -> syn::Result { for field in &fields.named { if let Some(ident) = &field.ident { let field_type = &field.ty; - let field_type_str = quote! { #field_type } + let field_type_str: String = quote! { #field_type } .to_string() // e.g.: "Option < String >" - .replace(' ', ""); // Remove spaces + .split_whitespace() + .collect(); // Remove all whitespace let mut ignore = false; diff --git a/sea-orm-macros/src/derives/arrow_schema.rs b/sea-orm-macros/src/derives/arrow_schema.rs index bf825985b7..346096fd5f 100644 --- a/sea-orm-macros/src/derives/arrow_schema.rs +++ b/sea-orm-macros/src/derives/arrow_schema.rs @@ -23,7 +23,10 @@ pub fn expand_derive_arrow_schema( let field_type = &field.ty; // Detect if field is Option for nullability - let type_string = quote! { #field_type }.to_string().replace(' ', ""); + let type_string: String = quote! { #field_type } + .to_string() + .split_whitespace() + .collect(); let is_nullable = type_string.starts_with("Option<"); // Parse field attributes @@ -282,7 +285,10 @@ fn column_type_to_arrow_datatype(col_type: &str, arrow_attrs: &ArrowFieldAttrs) /// Map Rust type to Arrow DataType (when no column_type specified) fn rust_type_to_arrow_datatype(field_type: &Type, arrow_attrs: &ArrowFieldAttrs) -> TokenStream { - let type_string = quote! { #field_type }.to_string().replace(' ', ""); + let type_string: String = quote! { #field_type } + .to_string() + .split_whitespace() + .collect(); // Strip Option<> wrapper if present let inner_type = if type_string.starts_with("Option<") { diff --git a/sea-orm-macros/src/derives/entity_model.rs b/sea-orm-macros/src/derives/entity_model.rs index fa3ee7dc09..a26fea20fd 100644 --- a/sea-orm-macros/src/derives/entity_model.rs +++ b/sea-orm-macros/src/derives/entity_model.rs @@ -405,9 +405,10 @@ pub fn expand_derive_entity_model( }; let field_type = &field.ty; - let field_type = quote! { #field_type } + let field_type: String = quote! { #field_type } .to_string() // e.g.: "Option < String >" - .replace(' ', ""); // Remove spaces + .split_whitespace() + .collect(); // Remove all whitespace if ignore { continue; diff --git a/sea-orm-macros/src/derives/model_ex.rs b/sea-orm-macros/src/derives/model_ex.rs index 166ad8ce4f..5606f61501 100644 --- a/sea-orm-macros/src/derives/model_ex.rs +++ b/sea-orm-macros/src/derives/model_ex.rs @@ -111,9 +111,10 @@ pub fn expand_sea_orm_model(input: ItemStruct, compact: bool) -> syn::Result" - .replace(' ', ""); // Remove spaces + .split_whitespace() + .collect(); // Remove all whitespace if is_compound_field(&field_type) { let entity_path = extract_compound_entity(&field_type); @@ -173,9 +174,10 @@ pub fn expand_derive_model_ex( for field in &fields.named { if let Some(ident) = &field.ident { let field_type = &field.ty; - let field_type = quote! { #field_type } + let field_type: String = quote! { #field_type } .to_string() // e.g.: "Option < String >" - .replace(' ', ""); // Remove spaces + .split_whitespace() + .collect(); // Remove all whitespace if is_compound_field(&field_type) { let compound_attrs = diff --git a/sea-orm-macros/src/derives/typed_column.rs b/sea-orm-macros/src/derives/typed_column.rs index b7f0ecd6b1..8048b85a95 100644 --- a/sea-orm-macros/src/derives/typed_column.rs +++ b/sea-orm-macros/src/derives/typed_column.rs @@ -24,9 +24,10 @@ pub fn expand_typed_column( Ident::new(&field_name.to_upper_camel_case(), ident.span()); let field_type = &field.ty; - let field_type = quote! { #field_type } + let field_type: String = quote! { #field_type } .to_string() // e.g.: "Option < String >" - .replace(' ', ""); // Remove spaces + .split_whitespace() + .collect(); // Remove all whitespace let mut ignore = false; let mut column_type = None; diff --git a/sea-orm-macros/src/derives/util.rs b/sea-orm-macros/src/derives/util.rs index 276435e67d..3b56ff76ff 100644 --- a/sea-orm-macros/src/derives/util.rs +++ b/sea-orm-macros/src/derives/util.rs @@ -4,9 +4,10 @@ use syn::{Field, Ident, Meta, MetaNameValue, punctuated::Punctuated, token::Comm /// Remove ignored fields and compound fields pub(crate) fn field_not_ignored(field: &Field) -> bool { let field_type = &field.ty; - let field_type = quote::quote! { #field_type } + let field_type: String = quote::quote! { #field_type } .to_string() // e.g.: "Option < String >" - .replace(' ', ""); // Remove spaces + .split_whitespace() + .collect(); // Remove all whitespace if is_compound_field(&field_type) { return false; diff --git a/sea-orm-macros/src/derives/value_type.rs b/sea-orm-macros/src/derives/value_type.rs index 77c8630535..f140eaeeae 100644 --- a/sea-orm-macros/src/derives/value_type.rs +++ b/sea-orm-macros/src/derives/value_type.rs @@ -139,9 +139,10 @@ impl DeriveValueTypeStruct { let field_span = field.span(); let ty = field.ty; - let field_type = quote! { #ty } + let field_type: String = quote! { #ty } .to_string() //E.g.: "Option < String >" - .replace(' ', ""); // Remove spaces + .split_whitespace() + .collect(); // Remove all whitespace let field_type = if field_type.starts_with("Option<") { &field_type[7..(field_type.len() - 1)] // Extract `T` out of `Option` } else {