Skip to Content
Cell Values (KalamCellValue)

Cell Values

KalamCellValue is the typed wrapper around each cell in query and subscription results.

Instead of parsing raw serde_json::Value at every call site, use the accessor methods on KalamCellValue.

Quick example

RUST
use kalam_client::KalamCellValue; let response = client    .execute_query("SELECT id, name, score FROM users", None, None, None)    .await?; for row in response.rows_as_maps() {    let id = row.get("id").and_then(|v| v.as_text());    let name = row.get("name").and_then(|v| v.as_text());    let score = row.get("score").and_then(|v| v.as_double());    println!("{id:?} {name:?} {score:?}");}

Row shapes

ContextType
QueryResponse::rows_as_maps()Vec<HashMap<String, KalamCellValue>>
QueryResponse::rows()Vec<Vec<KalamCellValue>> (positional)
LiveRowsEvent::RowsVec<HashMap<String, KalamCellValue>>
Low-level ChangeEvent rowsNamed or positional depending on event variant

Prefer named maps (rows_as_maps, live row maps) for application code.

Creating values

RUST
let cell = KalamCellValue::text("hello");let cell = KalamCellValue::int(42);let cell = KalamCellValue::boolean(true);let cell = KalamCellValue::null();let cell = KalamCellValue::from(serde_json::json!({"key": "value"}));

Type guards

KalamCellValue derefs to serde_json::Value, so you can use standard JSON checks:

RUST
cell.inner().is_null();cell.inner().is_string();cell.inner().is_number();

Prefer the typed accessors below for SQL column semantics.

Typed accessors

MethodSQL types
as_text()Text
as_small_int()SmallInt
as_int()Int
as_big_int()BigInt (handles string-encoded JSON for precision)
as_float() / as_double()Float / Double
as_decimal()Decimal
as_boolean()Boolean
as_timestamp()Timestamp (epoch value)

BigInt and large integers are often serialized as JSON strings — accessors handle both numeric and string forms.

Raw access

RUST
let raw: &serde_json::Value = cell.inner();let owned: serde_json::Value = cell.clone().into_inner();

Live subscription rows

RUST
if let LiveRowsEvent::Rows { rows, .. } = event? {    for row in rows {        let body = row.get("body").and_then(KalamCellValue::as_text);        println!("{body:?}");    }}

FILE columns

FILE values deserialize to structured JSON. Use file-specific helpers instead of parsing raw JSON by hand.

.as_file() -> Option<FileRef>

Parse a FILE column into table-agnostic metadata:

RUST
if let Some(file_ref) = cell.as_file() {    println!("{} ({})", file_ref.name, file_ref.format_size());    assert!(file_ref.is_image());}

FileRef alone does not include namespace/table — you need those to build download URLs.

.as_bound_file(&TableId) -> Option<BoundFileRef>

Parse and attach table context in one step. Reuse one TableId when parsing many rows from the same table:

RUST
use kalam_client::TableId; let table_id = TableId::from_strings("docs", "files");let bound = cell.as_bound_file(&table_id).expect("FILE column"); println!("{}", bound.relative_url());let download = client.download_bound_file(&bound, None).await?;

See FILE Columns & Uploads for uploads, BoundFileRef, and download APIs.

Accessor summary

MethodReturnsUse for
as_text()Option<&str>Text columns
as_int() / as_big_int()numeric optionsInteger columns
as_file()Option<FileRef>FILE metadata without table context
as_bound_file(&TableId)Option<BoundFileRef>FILE metadata + download context

Next

Last updated on