Derive Macro scylla::SerializeRow

source ·
#[derive(SerializeRow)]
{
    // Attributes available to this derive:
    #[scylla]
}
Expand description

Derive macro for the SerializeRow trait which serializes given Rust structure into bind markers for a CQL statement.

At the moment, only structs with named fields are supported.

Serialization will fail if there are some bind markers/columns in the statement that don’t match to any of the Rust struct fields, or vice versa.

In case of failure, either BuiltinTypeCheckError or BuiltinSerializationError will be returned.

§Example

A UDT defined like this: Given a table and a query:

CREATE TABLE ks.my_t (a int PRIMARY KEY, b text, c blob);
INSERT INTO ks.my_t (a, b, c) VALUES (?, ?, ?);

…the values for the query can be serialized using the following struct:

#[derive(SerializeRow)]
struct MyValues {
    a: i32,
    b: Option<String>,
    c: Vec<u8>,
}

§Struct attributes

#[scylla(flavor = "flavor_name")]

Allows to choose one of the possible “flavors”, i.e. the way how the generated code will approach serialization. Possible flavors are:

  • "match_by_name" (default) - the generated implementation does not require the fields in the Rust struct to be in the same order as the columns/bind markers. During serialization, the implementation will take care to serialize the fields in the order which the database expects.
  • "enforce_order" - the generated implementation requires the fields in the Rust struct to be in the same order as the columns/bind markers. If the order is incorrect, type checking/serialization will fail. This is a less robust flavor than "match_by_name", but should be slightly more performant as it doesn’t need to perform lookups by name.

#[scylla(crate = crate_name)]

By default, the code generated by the derive macro will refer to the items defined by the driver (types, traits, etc.) via the ::scylla path. For example, it will refer to the SerializeRow trait using the following path:

use ::scylla::_macro_internal::SerializeRow;

Most users will simply add scylla to their dependencies, then use the derive macro and the path above will work. However, there are some niche cases where this path will not work:

  • The scylla crate is imported under a different name,
  • The scylla crate is not imported at all - the macro actually is defined in the scylla-macros crate and the generated code depends on items defined in scylla-cql.

It’s not possible to automatically resolve those issues in the procedural macro itself, so in those cases the user must provide an alternative path to either the scylla or scylla-cql crate.

`#[scylla(skip_name_checks)]

Specific only to the enforce_order flavor.

Skips checking Rust field names against names of the columns / bind markers. With this annotation, the generated implementation will allow mismatch between Rust struct field names and the column / bind markers, i.e. it’s OK if i-th Rust struct field has a different name than the column / bind marker. The values are still being type-checked.

§Field attributes

#[scylla(rename = "column_or_bind_marker_name")]

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.


Documentation for this macro can only be found in scylla crate - not in scylla-macros nor in scylla-cql. This is because of rustdocs limitations that are hard to explain here.