Overview
The SerializeValue trait enables serialization of Rust types into individual CQL column values. This is a low-level trait that handles type-safe conversion between Rust types and CQL protocol format.
Most users should use the #[derive(SerializeValue)] macro for custom types. Built-in Rust types already implement this trait.
Source: scylla-cql/src/serialize/value.rs:31
Trait Definition
pub trait SerializeValue {
fn serialize<'b>(
&self,
typ: &ColumnType,
writer: CellWriter<'b>,
) -> Result<WrittenCellProof<'b>, SerializationError>;
}
Method
serialize
Serializes the value to the given CQL type.
fn serialize<'b>(
&self,
typ: &ColumnType,
writer: CellWriter<'b>,
) -> Result<WrittenCellProof<'b>, SerializationError>
Target CQL column type to serialize to
Writer for the serialized value bytes
result
Result<WrittenCellProof<'b>, SerializationError>
Proof that value was written correctly, or serialization error
Built-in Implementations
Numeric Types
impl SerializeValue for i8 // CQL: tinyint
impl SerializeValue for i16 // CQL: smallint
impl SerializeValue for i32 // CQL: int
impl SerializeValue for i64 // CQL: bigint
impl SerializeValue for f32 // CQL: float
impl SerializeValue for f64 // CQL: double
Example:
let value: i32 = 42;
// Serializes to CQL int type
Boolean
impl SerializeValue for bool // CQL: boolean
String Types
impl SerializeValue for str // CQL: text, ascii
impl SerializeValue for String // CQL: text, ascii
Example:
let text = "Hello, world!";
// Serializes to CQL text or ascii
Binary Types
impl SerializeValue for &[u8] // CQL: blob
impl SerializeValue for Vec<u8> // CQL: blob
impl SerializeValue for [u8; N] // CQL: blob
impl SerializeValue for Bytes // CQL: blob
Example:
let data = vec![0x01, 0x02, 0x03];
// Serializes to CQL blob
UUID Types
impl SerializeValue for Uuid // CQL: uuid
impl SerializeValue for CqlTimeuuid // CQL: timeuuid
Example:
use uuid::Uuid;
let id = Uuid::new_v4();
// Serializes to CQL uuid
IP Address
impl SerializeValue for IpAddr // CQL: inet
Example:
use std::net::IpAddr;
let ip: IpAddr = "127.0.0.1".parse()?;
// Serializes to CQL inet
Date and Time Types
impl SerializeValue for CqlDate // CQL: date
impl SerializeValue for CqlTime // CQL: time
impl SerializeValue for CqlTimestamp // CQL: timestamp
impl SerializeValue for CqlDuration // CQL: duration
With chrono-04 Feature
impl SerializeValue for chrono_04::NaiveDate // CQL: date
impl SerializeValue for chrono_04::NaiveTime // CQL: time
impl SerializeValue for chrono_04::DateTime<Utc> // CQL: timestamp
With time-03 Feature
impl SerializeValue for time_03::Date // CQL: date
impl SerializeValue for time_03::Time // CQL: time
impl SerializeValue for time_03::OffsetDateTime // CQL: timestamp
Arbitrary Precision Types
impl SerializeValue for CqlVarint // CQL: varint
impl SerializeValue for CqlDecimal // CQL: decimal
impl SerializeValue for Counter // CQL: counter
With num-bigint-03 Feature
impl SerializeValue for num_bigint_03::BigInt // CQL: varint
With num-bigint-04 Feature
impl SerializeValue for num_bigint_04::BigInt // CQL: varint
With bigdecimal-04 Feature
impl SerializeValue for bigdecimal_04::BigDecimal // CQL: decimal
Special Values
Option
impl<T: SerializeValue> SerializeValue for Option<T>
Serializes None as CQL NULL.
Example:
let maybe_name: Option<String> = None;
// Serializes to CQL NULL
let name: Option<String> = Some("Alice".to_string());
// Serializes to CQL text
Unset
impl SerializeValue for Unset
Represents an unset value (different from NULL).
MaybeUnset
impl<V: SerializeValue> SerializeValue for MaybeUnset<V>
Either a value or unset.
Example:
use scylla::value::MaybeUnset;
let value = MaybeUnset::Set(42);
let unset = MaybeUnset::<i32>::Unset;
MaybeEmpty
impl<T: SerializeValue + Emptiable> SerializeValue for MaybeEmpty<T>
For types that support CQL empty values.
Collections
Vec and Slice
impl<T: SerializeValue> SerializeValue for Vec<T> // CQL: list<T>, set<T>, vector<T, N>
impl<T: SerializeValue> SerializeValue for [T] // CQL: list<T>, set<T>, vector<T, N>
Example:
let numbers = vec![1, 2, 3, 4, 5];
// Serializes to CQL list<int>
HashSet
impl<V: SerializeValue, S: BuildHasher + Default> SerializeValue for HashSet<V, S> // CQL: set<V>
Example:
use std::collections::HashSet;
let mut tags = HashSet::new();
tags.insert("rust".to_string());
tags.insert("database".to_string());
// Serializes to CQL set<text>
BTreeSet
impl<V: SerializeValue> SerializeValue for BTreeSet<V> // CQL: set<V>
HashMap
impl<K: SerializeValue, V: SerializeValue, S: BuildHasher> SerializeValue for HashMap<K, V, S> // CQL: map<K, V>
Example:
use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert("Alice", 100);
scores.insert("Bob", 95);
// Serializes to CQL map<text, int>
BTreeMap
impl<K: SerializeValue, V: SerializeValue> SerializeValue for BTreeMap<K, V> // CQL: map<K, V>
Tuples
impl<T0: SerializeValue> SerializeValue for (T0,)
impl<T0: SerializeValue, T1: SerializeValue> SerializeValue for (T0, T1)
// ... up to 16 elements
Example:
let location = (40.7128, -74.0060); // latitude, longitude
// Serializes to CQL tuple<double, double>
CqlValue
impl SerializeValue for CqlValue
Dynamic CQL value that can hold any CQL type.
Example:
use scylla::value::CqlValue;
let value = CqlValue::Int(42);
let text = CqlValue::Text("Hello".to_string());
Smart Pointers
impl<T: SerializeValue + ?Sized> SerializeValue for &T
impl<T: SerializeValue + ?Sized> SerializeValue for Box<T>
impl<T: SerializeValue + ?Sized> SerializeValue for Arc<T>
impl<T: SerializeValue + ?Sized + ToOwned> SerializeValue for Cow<'_, T>
Secrecy Support
With secrecy-08 Feature
impl<V: SerializeValue + Zeroize> SerializeValue for secrecy_08::Secret<V>
With secrecy-10 Feature
impl<V: SerializeValue + Zeroize + ?Sized> SerializeValue for secrecy_10::SecretBox<V>
Derive Macro
The #[derive(SerializeValue)] macro implements SerializeValue for custom types (structs and enums).
UDT Serialization
use scylla::macros::SerializeValue;
#[derive(SerializeValue)]
struct Address {
street: String,
city: String,
zip: i32,
}
let addr = Address {
street: "123 Main St".to_string(),
city: "Springfield".to_string(),
zip: 12345,
};
Field Attributes
#[scylla(rename = "...")]
#[derive(SerializeValue)]
struct User {
#[scylla(rename = "user_id")]
id: i32,
name: String,
}
#[scylla(skip)]
#[derive(SerializeValue)]
struct User {
id: i32,
name: String,
#[scylla(skip)]
local_cache: String,
}
Type Attributes
#[scylla(crate = ...)]
#[derive(SerializeValue)]
#[scylla(crate = "scylla_cql")]
struct CustomType {
field: i32,
}
Error Types
BuiltinTypeCheckError
pub struct BuiltinTypeCheckError {
pub rust_name: &'static str,
pub got: ColumnType<'static>,
pub kind: BuiltinTypeCheckErrorKind,
}
BuiltinTypeCheckErrorKind
pub enum BuiltinTypeCheckErrorKind {
MismatchedType { expected: &'static [ColumnType<'static>] },
NotEmptyable,
SetOrListError(SetOrListTypeCheckErrorKind),
MapError(MapTypeCheckErrorKind),
TupleError(TupleTypeCheckErrorKind),
UdtError(UdtTypeCheckErrorKind),
}
BuiltinSerializationError
pub struct BuiltinSerializationError {
pub rust_name: &'static str,
pub got: ColumnType<'static>,
pub kind: BuiltinSerializationErrorKind,
}
BuiltinSerializationErrorKind
pub enum BuiltinSerializationErrorKind {
SizeOverflow,
ValueOverflow,
SetOrListError(SetOrListSerializationErrorKind),
VectorError(VectorSerializationErrorKind),
MapError(MapSerializationErrorKind),
TupleError(TupleSerializationErrorKind),
UdtError(UdtSerializationErrorKind),
}
Examples
Basic Type Serialization
// Numeric types
let age: i32 = 42;
let height: f64 = 1.75;
// Strings
let name = "Alice";
let email = "[email protected]".to_string();
// Binary data
let data = vec![0x01, 0x02, 0x03];
// UUID
let id = uuid::Uuid::new_v4();
// All these work with prepared statements
session.execute_unpaged(&prepared, (age, height, name, email, data, id)).await?;
Collection Serialization
use std::collections::{HashMap, HashSet};
// List
let numbers = vec![1, 2, 3, 4, 5];
// Set
let mut tags = HashSet::new();
tags.insert("rust");
tags.insert("scylla");
// Map
let mut config = HashMap::new();
config.insert("timeout", 30);
config.insert("retries", 3);
session.execute_unpaged(&prepared, (numbers, tags, config)).await?;
UDT Serialization
use scylla::macros::SerializeValue;
// CREATE TYPE address (street text, city text, zip int);
#[derive(SerializeValue)]
struct Address {
street: String,
city: String,
zip: i32,
}
let addr = Address {
street: "123 Main St".to_string(),
city: "Springfield".to_string(),
zip: 12345,
};
// INSERT INTO users (id, name, address) VALUES (?, ?, ?)
session.execute_unpaged(&prepared, (1, "Alice", addr)).await?;
Nullable and Unset Values
use scylla::value::{MaybeUnset, Unset};
// Optional value - None becomes NULL
let maybe_email: Option<String> = None;
// Unset value - doesn't update the column
let unset_field = Unset;
// Maybe unset
let field = MaybeUnset::Set(42);
let unchanged = MaybeUnset::<i32>::Unset;
session.execute_unpaged(&prepared, (maybe_email, unset_field, field)).await?;
See Also