Overview
This page documents the mapping between CQL (Cassandra Query Language) data types and Rust types in the ScyllaDB Rust Driver.
Type Mapping Table
| CQL Type | Rust Type(s) | Notes |
|---|
boolean | bool | |
tinyint | i8 | |
smallint | i16 | |
int | i32 | |
bigint | i64 | |
float | f32 | IEEE-754 32-bit |
double | f64 | IEEE-754 64-bit |
varint | CqlVarint, CqlVarintBorrowed<'_>, num_bigint::BigInt | Requires feature flag for BigInt |
decimal | CqlDecimal, CqlDecimalBorrowed<'_>, bigdecimal_04::BigDecimal | Requires feature flag for BigDecimal |
ascii | &str, String | ASCII-only string |
text / varchar | &str, String | UTF-8 string |
blob | &[u8], Vec<u8>, Bytes | Binary data |
uuid | uuid::Uuid | Any UUID version |
timeuuid | CqlTimeuuid | UUID v1 with special ordering |
inet | std::net::IpAddr | IPv4 or IPv6 |
date | CqlDate, chrono::NaiveDate, time::Date | Days since epoch |
time | CqlTime, chrono::NaiveTime, time::Time | Nanoseconds since midnight |
timestamp | CqlTimestamp, chrono::DateTime<Utc>, time::OffsetDateTime | Milliseconds since Unix epoch |
duration | CqlDuration | Months, days, nanoseconds |
counter | Counter | Special counter type |
list<T> | Vec<T> | Ordered collection |
set<T> | Vec<T>, HashSet<T>, BTreeSet<T> | Unordered unique values |
map<K, V> | HashMap<K, V>, BTreeMap<K, V> | Key-value pairs |
vector<T, N> | Vec<T> | Fixed-size vector (N elements) |
tuple<T1, T2, ...> | (T1, T2, ...) | Fixed-size heterogeneous collection |
| User-Defined Type | Struct with #[derive(SerializeValue)] or #[derive(DeserializeValue)] | Custom types |
Numeric Types
Fixed-Size Integers
// CQL: tinyint, smallint, int, bigint
let tiny: i8 = -128;
let small: i16 = -32768;
let normal: i32 = -2147483648;
let big: i64 = -9223372036854775808;
Floating Point
// CQL: float, double
let f: f32 = 3.14;
let d: f64 = 2.718281828;
Arbitrary Precision
Varint
use scylla::value::CqlVarint;
// Native implementation
let varint = CqlVarint::from_signed_bytes_be_slice(&[0x01, 0x02, 0x03]);
// With num-bigint-03 feature
#[cfg(feature = "num-bigint-03")]
use num_bigint_03::BigInt;
#[cfg(feature = "num-bigint-03")]
let bigint = BigInt::from(12345);
// With num-bigint-04 feature
#[cfg(feature = "num-bigint-04")]
use num_bigint_04::BigInt;
#[cfg(feature = "num-bigint-04")]
let bigint = BigInt::from(12345);
Decimal
use scylla::value::CqlDecimal;
// Native implementation
let decimal = CqlDecimal::from_signed_be_bytes_slice_and_exponent(&[0x01], 2);
// With bigdecimal-04 feature
#[cfg(feature = "bigdecimal-04")]
use bigdecimal_04::BigDecimal;
#[cfg(feature = "bigdecimal-04")]
let decimal = BigDecimal::from(123.45);
Counter
use scylla::value::Counter;
let counter = Counter(42);
Counters can only be updated with UPDATE statements, not INSERT.
String Types
Text (UTF-8)
// CQL: text, varchar
let borrowed: &str = "Hello, World!";
let owned: String = "Hello, World!".to_string();
ASCII
// CQL: ascii
let ascii: String = "ASCII only".to_string();
The driver validates that ASCII values only contain ASCII characters during serialization.
Binary Type
// CQL: blob
let borrowed: &[u8] = &[0x01, 0x02, 0x03];
let owned: Vec<u8> = vec![0x01, 0x02, 0x03];
// With bytes crate
use bytes::Bytes;
let bytes = Bytes::from_static(&[0x01, 0x02, 0x03]);
UUID Types
UUID
use uuid::Uuid;
// CQL: uuid
let id = Uuid::new_v4();
let parsed = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000")?;
Timeuuid
use scylla::value::CqlTimeuuid;
use uuid::Uuid;
// CQL: timeuuid
let timeuuid = CqlTimeuuid::from(Uuid::now_v1(&[/* node */]));
CqlTimeuuid uses special comparison logic that follows ScyllaDB/Cassandra semantics for timeuuid ordering.
Date and Time Types
Date
use scylla::value::CqlDate;
// Native type: days since -5877641-06-23
let date = CqlDate(2_u32.pow(31));
// With chrono-04 feature
#[cfg(feature = "chrono-04")]
use chrono::NaiveDate;
#[cfg(feature = "chrono-04")]
let date = NaiveDate::from_ymd_opt(2024, 1, 1).unwrap();
// With time-03 feature
#[cfg(feature = "time-03")]
use time::Date;
#[cfg(feature = "time-03")]
let date = Date::from_calendar_date(2024, time::Month::January, 1)?;
Time
use scylla::value::CqlTime;
// Native type: nanoseconds since midnight
let time = CqlTime(3600_000_000_000);
// With chrono-04 feature
#[cfg(feature = "chrono-04")]
use chrono::NaiveTime;
#[cfg(feature = "chrono-04")]
let time = NaiveTime::from_hms_opt(12, 0, 0).unwrap();
// With time-03 feature
#[cfg(feature = "time-03")]
use time::Time;
#[cfg(feature = "time-03")]
let time = Time::from_hms(12, 0, 0)?;
Timestamp
use scylla::value::CqlTimestamp;
// Native type: milliseconds since Unix epoch
let timestamp = CqlTimestamp(1234567890000);
// With chrono-04 feature
#[cfg(feature = "chrono-04")]
use chrono::{DateTime, Utc};
#[cfg(feature = "chrono-04")]
let timestamp = Utc::now();
// With time-03 feature
#[cfg(feature = "time-03")]
use time::OffsetDateTime;
#[cfg(feature = "time-03")]
let timestamp = OffsetDateTime::now_utc();
Duration
use scylla::value::CqlDuration;
// CQL: duration
let duration = CqlDuration {
months: 1,
days: 2,
nanoseconds: 3_000_000_000,
};
Network Type
use std::net::IpAddr;
// CQL: inet
let ipv4: IpAddr = "127.0.0.1".parse()?;
let ipv6: IpAddr = "::1".parse()?;
Collection Types
List
// CQL: list<int>
let numbers: Vec<i32> = vec![1, 2, 3, 4, 5];
Set
use std::collections::HashSet;
// CQL: set<text>
let mut tags = HashSet::new();
tags.insert("rust".to_string());
tags.insert("scylla".to_string());
// Can also use Vec or BTreeSet
let tags_vec: Vec<String> = vec!["rust".to_string(), "scylla".to_string()];
Map
use std::collections::HashMap;
// CQL: map<text, int>
let mut scores = HashMap::new();
scores.insert("Alice".to_string(), 100);
scores.insert("Bob".to_string(), 95);
// Can also use BTreeMap
use std::collections::BTreeMap;
let scores_btree: BTreeMap<String, i32> = BTreeMap::new();
Vector (Fixed-Size)
// CQL: vector<float, 3>
let embedding: Vec<f32> = vec![0.1, 0.2, 0.3];
The length must match the declared size in the CQL type.
Tuple
// CQL: tuple<int, text, boolean>
let data: (i32, String, bool) = (42, "hello".to_string(), true);
// Nested tuples
let nested: (i32, (String, bool)) = (42, ("hello".to_string(), true));
User-Defined Types
use scylla::macros::{SerializeValue, DeserializeValue};
// CQL:
// CREATE TYPE address (
// street text,
// city text,
// zip int
// );
#[derive(SerializeValue, DeserializeValue, Debug)]
struct Address {
street: String,
city: String,
zip: i32,
}
let addr = Address {
street: "123 Main St".to_string(),
city: "Springfield".to_string(),
zip: 12345,
};
NULL and Empty Values
NULL
// Use Option<T> for nullable columns
let maybe_email: Option<String> = None; // NULL
let email: Option<String> = Some("[email protected]".to_string()); // Not NULL
Unset
use scylla::value::{Unset, MaybeUnset};
// Unset value (doesn't update the column)
let unset_field = Unset;
// Maybe unset
let field = MaybeUnset::Set(42);
let unchanged = MaybeUnset::<i32>::Unset;
Empty
use scylla::value::MaybeEmpty;
// For emptiable types (numeric types, etc.)
let empty = MaybeEmpty::<i32>::Empty;
let value = MaybeEmpty::Value(42);
Feature Flags
Date/Time Features
[dependencies]
scylla = { version = "*", features = ["chrono-04"] }
# or
scylla = { version = "*", features = ["time-03"] }
BigInt Features
[dependencies]
scylla = { version = "*", features = ["num-bigint-03"] }
# or
scylla = { version = "*", features = ["num-bigint-04"] }
BigDecimal Features
[dependencies]
scylla = { version = "*", features = ["bigdecimal-04"] }
Secrecy Features
[dependencies]
scylla = { version = "*", features = ["secrecy-08"] }
# or
scylla = { version = "*", features = ["secrecy-10"] }
Type Conversion Examples
Serialization
use scylla::serialize::value::SerializeValue;
// Primitive to CQL
let value: i32 = 42;
// Serializes to CQL int
// Collection to CQL
let list = vec![1, 2, 3];
// Serializes to CQL list<int>
// Struct to CQL UDT
#[derive(SerializeValue)]
struct MyType { field: i32 }
// Serializes to CQL UDT
Deserialization
use scylla::deserialize::value::DeserializeValue;
// CQL int to Rust
let value: i32 = // ... from CQL int
// CQL list<int> to Rust
let list: Vec<i32> = // ... from CQL list<int>
// CQL UDT to Rust struct
#[derive(DeserializeValue)]
struct MyType { field: i32 }
let my_val: MyType = // ... from CQL UDT
See Also