Skip to main content

Overview

The DeserializeValue trait enables deserialization of individual CQL column values into Rust types. It provides type-safe conversion from CQL protocol format to Rust data types.
Most users will use built-in implementations for standard Rust types. The #[derive(DeserializeValue)] macro is available for custom types (UDTs, enums).
Source: scylla-cql/src/deserialize/value.rs:48

Trait Definition

pub trait DeserializeValue<'frame, 'metadata>
where
    Self: Sized,
{
    fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError>;

    fn deserialize(
        typ: &'metadata ColumnType<'metadata>,
        v: Option<FrameSlice<'frame>>,
    ) -> Result<Self, DeserializationError>;
}

Methods

type_check

Verifies that the CQL column type matches the Rust type’s expectations.
fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError>
typ
&ColumnType
required
CQL column type from result metadata
result
Result<(), TypeCheckError>
Ok(()) if types are compatible, or type check error

deserialize

Deserializes a value from its serialized representation.
fn deserialize(
    typ: &'metadata ColumnType<'metadata>,
    v: Option<FrameSlice<'frame>>,
) -> Result<Self, DeserializationError>
typ
&ColumnType
required
CQL column type metadata
v
Option<FrameSlice>
required
Serialized value bytes, or None for NULL
result
Result<Self, DeserializationError>
Deserialized Rust value, or deserialization error

Built-in Implementations

Numeric Types

impl DeserializeValue for i8      // CQL: tinyint
impl DeserializeValue for i16     // CQL: smallint
impl DeserializeValue for i32     // CQL: int
impl DeserializeValue for i64     // CQL: bigint
impl DeserializeValue for f32     // CQL: float
impl DeserializeValue for f64     // CQL: double

Boolean

impl DeserializeValue for bool    // CQL: boolean

String Types

impl DeserializeValue for &'a str     // CQL: text, ascii (borrowed)
impl DeserializeValue for String      // CQL: text, ascii (owned)

Binary Types

impl DeserializeValue for &'a [u8]    // CQL: blob (borrowed)
impl DeserializeValue for Vec<u8>     // CQL: blob (owned)
impl DeserializeValue for Bytes       // CQL: blob (bytes crate)

UUID Types

impl DeserializeValue for Uuid        // CQL: uuid
impl DeserializeValue for CqlTimeuuid // CQL: timeuuid

IP Address

impl DeserializeValue for IpAddr      // CQL: inet

Date and Time Types

impl DeserializeValue for CqlDate       // CQL: date
impl DeserializeValue for CqlTime       // CQL: time
impl DeserializeValue for CqlTimestamp  // CQL: timestamp
impl DeserializeValue for CqlDuration   // CQL: duration

With chrono-04 Feature

impl DeserializeValue for chrono_04::NaiveDate        // CQL: date
impl DeserializeValue for chrono_04::NaiveTime        // CQL: time
impl DeserializeValue for chrono_04::DateTime<Utc>    // CQL: timestamp

With time-03 Feature

impl DeserializeValue for time_03::Date               // CQL: date
impl DeserializeValue for time_03::Time               // CQL: time
impl DeserializeValue for time_03::OffsetDateTime     // CQL: timestamp

Arbitrary Precision Types

impl DeserializeValue for CqlVarint         // CQL: varint
impl DeserializeValue for CqlVarintBorrowed // CQL: varint (borrowed)
impl DeserializeValue for CqlDecimal        // CQL: decimal
impl DeserializeValue for CqlDecimalBorrowed // CQL: decimal (borrowed)
impl DeserializeValue for Counter           // CQL: counter

With num-bigint-03 Feature

impl DeserializeValue for num_bigint_03::BigInt  // CQL: varint

With num-bigint-04 Feature

impl DeserializeValue for num_bigint_04::BigInt  // CQL: varint

With bigdecimal-04 Feature

impl DeserializeValue for bigdecimal_04::BigDecimal  // CQL: decimal

Option (Nullable)

impl<T: DeserializeValue> DeserializeValue for Option<T>
Deserializes None from CQL NULL values. Example:
let email: Option<String> = // ... from nullable column
match email {
    Some(e) => println!("Email: {}", e),
    None => println!("No email provided"),
}

MaybeEmpty

impl<T: DeserializeValue + Emptiable> DeserializeValue for MaybeEmpty<T>
Deserializes empty CQL values (0 bytes, distinct from NULL).

Collections

Vec

impl<T: DeserializeValue> DeserializeValue for Vec<T>  // CQL: list<T>, set<T>, vector<T, N>
Example:
let tags: Vec<String> = // ... from list<text> or set<text>

HashSet

impl<T: DeserializeValue + Eq + Hash, S: BuildHasher + Default> DeserializeValue for HashSet<T, S>
Example:
use std::collections::HashSet;

let tags: HashSet<String> = // ... from set<text>

BTreeSet

impl<T: DeserializeValue + Ord> DeserializeValue for BTreeSet<T>

HashMap

impl<K: DeserializeValue + Eq + Hash, V: DeserializeValue, S: BuildHasher + Default> DeserializeValue for HashMap<K, V, S>
Example:
use std::collections::HashMap;

let scores: HashMap<String, i32> = // ... from map<text, int>

BTreeMap

impl<K: DeserializeValue + Ord, V: DeserializeValue> DeserializeValue for BTreeMap<K, V>

Tuples

impl<T0: DeserializeValue> DeserializeValue for (T0,)
impl<T0: DeserializeValue, T1: DeserializeValue> DeserializeValue for (T0, T1)
// ... up to 16 elements
Example:
let coords: (f64, f64) = // ... from tuple<double, double>

CqlValue

impl DeserializeValue for CqlValue
Dynamic value that can represent any CQL type. Example:
use scylla::value::CqlValue;

let value: CqlValue = // ... from any CQL type
match value {
    CqlValue::Int(i) => println!("Integer: {}", i),
    CqlValue::Text(s) => println!("Text: {}", s),
    _ => println!("Other type"),
}

Secrecy Support

With secrecy-08 Feature

impl<T: DeserializeValue + Zeroize> DeserializeValue for secrecy_08::Secret<T>

With secrecy-10 Feature

impl<T: DeserializeValue + Zeroize> DeserializeValue for secrecy_10::SecretBox<T>
impl DeserializeValue for secrecy_10::SecretString
impl<S: DeserializeValue + Zeroize> DeserializeValue for secrecy_10::SecretSlice<S>

Collection Iterators

ListlikeIterator

Iterates over CQL list or set elements.
pub struct ListlikeIterator<'frame, 'metadata, T> {
    // ... internal fields
}
Example:
use scylla::deserialize::value::ListlikeIterator;

let iter: ListlikeIterator<String> = // ... deserialized from list<text>
for item in iter {
    let value = item?;
    println!("{}", value);
}

MapIterator

Iterates over CQL map entries.
pub struct MapIterator<'frame, 'metadata, K, V> {
    // ... internal fields
}
Example:
use scylla::deserialize::value::MapIterator;

let iter: MapIterator<String, i32> = // ... from map<text, int>
for entry in iter {
    let (key, value) = entry?;
    println!("{}: {}", key, value);
}

VectorIterator

Iterates over CQL vector elements.
pub struct VectorIterator<'frame, 'metadata, T> {
    // ... internal fields
}

UdtIterator

Iterates over UDT fields.
pub struct UdtIterator<'frame, 'metadata> {
    // ... internal fields
}

Derive Macro

The #[derive(DeserializeValue)] macro implements deserialization for custom types.

UDT Deserialization

use scylla::macros::DeserializeValue;

// CREATE TYPE address (street text, city text, zip int);
#[derive(DeserializeValue, Debug)]
struct Address {
    street: String,
    city: String,
    zip: i32,
}

let addr: Address = // ... from address UDT column

Field Attributes

#[scylla(rename = "...")]

#[derive(DeserializeValue)]
struct User {
    #[scylla(rename = "user_id")]
    id: i32,
    name: String,
}

#[scylla(skip)]

#[derive(DeserializeValue)]
struct User {
    id: i32,
    name: String,
    #[scylla(skip)]
    cached: String,  // Not from DB
}

Error Types

BuiltinTypeCheckError

pub struct BuiltinTypeCheckError {
    pub rust_name: &'static str,
    pub cql_types: Vec<ColumnType<'static>>,
    pub kind: BuiltinTypeCheckErrorKind,
}

BuiltinDeserializationError

pub struct BuiltinDeserializationError {
    pub rust_name: &'static str,
    pub kind: BuiltinDeserializationErrorKind,
}

BuiltinDeserializationErrorKind

pub enum BuiltinDeserializationErrorKind {
    RawCqlBytesReadError(LowLevelDeserializationError),
    ExpectedAscii,
    InvalidUtf8(std::str::Utf8Error),
    BadDecimalScale(LowLevelDeserializationError),
    BadDate { date_field: &'static str, err: LowLevelDeserializationError },
    ValueOverflow,
    BadInetLength { got: usize },
    // ... and more
}

Examples

Basic Type Deserialization

// Numeric types
let id: i32 = // ... from int column
let height: f64 = // ... from double column

// Strings
let name: String = // ... from text column
let email: &str = // ... from text column (borrowed)

// UUID
use uuid::Uuid;
let id: Uuid = // ... from uuid column

// Binary data
let data: Vec<u8> = // ... from blob column

Collection Deserialization

use std::collections::{HashMap, HashSet};

// List
let numbers: Vec<i32> = // ... from list<int>

// Set
let tags: HashSet<String> = // ... from set<text>

// Map
let scores: HashMap<String, i32> = // ... from map<text, int>

// Vector
let embeddings: Vec<f32> = // ... from vector<float, 128>

UDT Deserialization

use scylla::macros::DeserializeValue;

#[derive(DeserializeValue, Debug)]
struct Address {
    street: String,
    city: String,
    zip: i32,
}

#[derive(DeserializeRow)]
struct User {
    id: i32,
    name: String,
    address: Address,  // Nested UDT
}

let users: Vec<User> = session
    .query_unpaged("SELECT id, name, address FROM users", &[])
    .await?
    .rows_typed::<User>()?;

Nullable Values

let email: Option<String> = // ... from nullable text column
let age: Option<i32> = // ... from nullable int column

match email {
    Some(e) => println!("Email: {}", e),
    None => println!("No email"),
}

Date and Time

use scylla::value::{CqlDate, CqlTime, CqlTimestamp};

let date: CqlDate = // ... from date column
let time: CqlTime = // ... from time column
let timestamp: CqlTimestamp = // ... from timestamp column

// With chrono feature
use chrono::{NaiveDate, DateTime, Utc};

let date: NaiveDate = // ... from date column
let timestamp: DateTime<Utc> = // ... from timestamp column

See Also

Build docs developers (and LLMs) love