Skip to content

Commit 8b579e6

Browse files
committed
Allow non-rust idents for renamed field names in SerializeValue
this adds support for UDTs that have fields that are not valid rust idents but are valid scylla field names
1 parent 1c0d353 commit 8b579e6

File tree

2 files changed

+34
-7
lines changed

2 files changed

+34
-7
lines changed

scylla-cql/src/types/serialize/value.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2824,4 +2824,32 @@ pub(crate) mod tests {
28242824

28252825
assert_eq!(reference, row);
28262826
}
2827+
2828+
#[test]
2829+
fn test_udt_with_non_rust_ident() {
2830+
#[derive(SerializeValue, Debug)]
2831+
#[scylla(crate = crate)]
2832+
struct UdtWithNonRustIdent {
2833+
#[scylla(rename = "a$a")]
2834+
a: i32,
2835+
}
2836+
2837+
let typ = ColumnType::UserDefinedType {
2838+
type_name: "typ".into(),
2839+
keyspace: "ks".into(),
2840+
field_types: vec![("a$a".into(), ColumnType::Int)],
2841+
};
2842+
let value = UdtWithNonRustIdent { a: 42 };
2843+
2844+
let mut reference = Vec::new();
2845+
// Total length of the struct
2846+
reference.extend_from_slice(&8i32.to_be_bytes());
2847+
// Field 'a'
2848+
reference.extend_from_slice(&(std::mem::size_of_val(&value.a) as i32).to_be_bytes());
2849+
reference.extend_from_slice(&value.a.to_be_bytes());
2850+
2851+
let udt = do_serialize(value, &typ);
2852+
2853+
assert_eq!(reference, udt);
2854+
}
28272855
}

scylla-macros/src/serialize/value.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use std::collections::HashMap;
22

33
use darling::FromAttributes;
44
use proc_macro::TokenStream;
5-
use proc_macro2::Span;
65
use syn::parse_quote;
76

87
use crate::Flavor;
@@ -327,14 +326,14 @@ impl Generator for FieldSortingGenerator<'_> {
327326
.generate_udt_type_match(parse_quote!(#crate_path::UdtTypeCheckErrorKind::NotUdt)),
328327
);
329328

330-
fn make_visited_flag_ident(field_name: &str) -> syn::Ident {
331-
syn::Ident::new(&format!("visited_flag_{}", field_name), Span::call_site())
329+
fn make_visited_flag_ident(field_name: &syn::Ident) -> syn::Ident {
330+
syn::Ident::new(&format!("visited_flag_{}", field_name), field_name.span())
332331
}
333332

334333
// Generate a "visited" flag for each field
335-
let visited_flag_names = rust_field_names
334+
let visited_flag_names = rust_field_idents
336335
.iter()
337-
.map(|s| make_visited_flag_ident(s))
336+
.map(make_visited_flag_ident)
338337
.collect::<Vec<_>>();
339338
statements.extend::<Vec<_>>(parse_quote! {
340339
#(let mut #visited_flag_names = false;)*
@@ -347,11 +346,11 @@ impl Generator for FieldSortingGenerator<'_> {
347346
.fields
348347
.iter()
349348
.filter(|f| !f.attrs.ignore_missing)
350-
.map(|f| f.field_name());
349+
.map(|f| &f.ident);
351350
// An iterator over visited flags of Rust fields that can't be ignored
352351
// (i.e., if UDT misses a corresponding field, an error should be raised).
353352
let nonignorable_visited_flag_names =
354-
nonignorable_rust_field_names.map(|s| make_visited_flag_ident(&s));
353+
nonignorable_rust_field_names.map(make_visited_flag_ident);
355354

356355
// Generate a variable that counts down visited fields.
357356
let field_count = self.ctx.fields.len();

0 commit comments

Comments
 (0)