diff --git a/scylla-cql/src/macros.rs b/scylla-cql/src/macros.rs index 0593112668..92b89f2c02 100644 --- a/scylla-cql/src/macros.rs +++ b/scylla-cql/src/macros.rs @@ -117,6 +117,10 @@ pub use scylla_macros::ValueList; /// /// Serializes the field to the UDT struct field with given name instead of /// its Rust name. +/// +/// `#[scylla(skip)]` +/// +/// Don't use the field during serialization. pub use scylla_macros::SerializeCql; /// Derive macro for the [`SerializeRow`](crate::types::serialize::row::SerializeRow) trait @@ -211,6 +215,10 @@ pub use scylla_macros::SerializeCql; /// /// Serializes the field to the column / bind marker with given name instead of /// its Rust name. +/// +/// `#[scylla(skip)]` +/// +/// Don't use the field during serialization. pub use scylla_macros::SerializeRow; // Reexports for derive(IntoUserType) diff --git a/scylla-cql/src/types/serialize/row.rs b/scylla-cql/src/types/serialize/row.rs index 451edb85ca..6c485ed147 100644 --- a/scylla-cql/src/types/serialize/row.rs +++ b/scylla-cql/src/types/serialize/row.rs @@ -1519,4 +1519,44 @@ mod tests { assert_eq!(reference, row); } + + #[derive(SerializeRow, Debug)] + #[scylla(crate = crate)] + struct TestRowWithSkippedFields { + a: String, + b: i32, + #[scylla(skip)] + #[allow(dead_code)] + skipped: Vec, + c: Vec, + } + + #[test] + fn test_row_serialization_with_skipped_field() { + let spec = [ + col("a", ColumnType::Text), + col("b", ColumnType::Int), + col("c", ColumnType::List(Box::new(ColumnType::BigInt))), + ]; + + let reference = do_serialize( + TestRowWithColumnSorting { + a: "Ala ma kota".to_owned(), + b: 42, + c: vec![1, 2, 3], + }, + &spec, + ); + let row = do_serialize( + TestRowWithSkippedFields { + a: "Ala ma kota".to_owned(), + b: 42, + skipped: vec!["abcd".to_owned(), "efgh".to_owned()], + c: vec![1, 2, 3], + }, + &spec, + ); + + assert_eq!(reference, row); + } } diff --git a/scylla-cql/src/types/serialize/value.rs b/scylla-cql/src/types/serialize/value.rs index 3980e06947..9e5a691be6 100644 --- a/scylla-cql/src/types/serialize/value.rs +++ b/scylla-cql/src/types/serialize/value.rs @@ -2692,4 +2692,51 @@ mod tests { BuiltinTypeCheckErrorKind::UdtError(UdtTypeCheckErrorKind::NoSuchFieldInUdt { .. }) )); } + + #[derive(SerializeCql, Debug)] + #[scylla(crate = crate, flavor = "enforce_order", skip_name_checks)] + struct TestUdtWithSkippedFields { + a: String, + b: i32, + #[scylla(skip)] + #[allow(dead_code)] + skipped: Vec, + c: Vec, + } + + #[test] + fn test_row_serialization_with_skipped_field() { + let typ = ColumnType::UserDefinedType { + type_name: "typ".to_string(), + keyspace: "ks".to_string(), + field_types: vec![ + ("a".to_string(), ColumnType::Text), + ("b".to_string(), ColumnType::Int), + ( + "c".to_string(), + ColumnType::List(Box::new(ColumnType::BigInt)), + ), + ], + }; + + let reference = do_serialize( + TestUdtWithFieldSorting { + a: "Ala ma kota".to_owned(), + b: 42, + c: vec![1, 2, 3], + }, + &typ, + ); + let row = do_serialize( + TestUdtWithSkippedFields { + a: "Ala ma kota".to_owned(), + b: 42, + skipped: vec!["abcd".to_owned(), "efgh".to_owned()], + c: vec![1, 2, 3], + }, + &typ, + ); + + assert_eq!(reference, row); + } } diff --git a/scylla-macros/src/serialize/cql.rs b/scylla-macros/src/serialize/cql.rs index 3ba74e671e..feb1819b4e 100644 --- a/scylla-macros/src/serialize/cql.rs +++ b/scylla-macros/src/serialize/cql.rs @@ -51,6 +51,9 @@ impl Field { #[darling(attributes(scylla))] struct FieldAttributes { rename: Option, + + #[darling(default)] + skip: bool, } struct Context { @@ -78,6 +81,9 @@ pub fn derive_serialize_cql(tokens_input: TokenStream) -> Result>()?; let ctx = Context { attributes, fields }; ctx.validate(&input.ident)?; diff --git a/scylla-macros/src/serialize/row.rs b/scylla-macros/src/serialize/row.rs index 122bed93dd..34bdce92c1 100644 --- a/scylla-macros/src/serialize/row.rs +++ b/scylla-macros/src/serialize/row.rs @@ -48,6 +48,9 @@ impl Field { #[darling(attributes(scylla))] struct FieldAttributes { rename: Option, + + #[darling(default)] + skip: bool, } struct Context { @@ -75,6 +78,9 @@ pub fn derive_serialize_row(tokens_input: TokenStream) -> Result>()?; let ctx = Context { attributes, fields }; ctx.validate(&input.ident)?;