Skip to main content
These are the “flat” DuckValue variants. All of their inner Rust types implement AppendAble, so you can bind and append them directly, and most primitive Rust types read back through FromDuckValue.

Booleans, integers, floats

FromDuckValue performs lossless widening: an INTEGER column reads cleanly into i32, i64, or i128. A value that does not fit the requested integer type is reported as Error::IntegralValueOutOfRange, never silently truncated.

128-bit integers

HugeInt (i128) and UHugeInt (u128) are first-class. DuckDB stores them as a struct of two 64-bit halves; better-duck-core encodes/decodes the full i128/u128 range. For f64 conversions use the helpers re-exported at the crate root:
These use DuckDB’s own routines and are lossy beyond f64’s 53-bit significand.

Text

Bind &str or String directly; build a value with DuckValue::text("…"). Invalid UTF-8 from a column surfaces as Error::Utf8Error.

Blobs — Blob

Blob is a newtype pub struct Blob(pub Vec<u8>) — distinct from a plain Vec<u8> so that Vec<T> is free to map to a LIST (see composite types).
A GEOMETRY column physically arrives as its WKB Blob. Types without read support yet surface as a DuckDBConversionError.

DECIMAL — DuckDecimal

DuckDecimal preserves the declared precision: the numeric value is mantissa * 10^(-scale).
  • new(value, width, scale) validates 1 <= width <= 38 (DECIMAL_MAX_WIDTH) and scale <= width, matching DuckDB’s bounds; otherwise DuckDBConversionError.
  • from_double rejects non-finite values and magnitudes that overflow width.
  • to_double is lossy beyond f64’s significand — read value/width/scale directly when exactness matters.
With the rust_decimal feature, DuckDecimal converts to/from rust_decimal::Decimal. A DuckDB scale beyond 28 (which rust_decimal cannot hold) is reported as precision loss, not silently truncated.

UUID — DuckUuid

pub struct DuckUuid(pub u128) holds the value in standard big-endian bit order — DuckUuid(0) is the nil UUID and ordering matches standard UUID ordering (the storage-level sign flip DuckDB uses internally is handled for you). With the uuid feature it round-trips with uuid::Uuid as a plain u128 passthrough.

BIT — DuckBit

pub struct DuckBit(pub Vec<u8>) stores DuckDB’s exact wire format: the first byte is the padding count (0–7), the rest is bit-packed data, MSB first — so a value round-trips byte-for-byte.

BIGNUM — DuckBignum

An arbitrary-precision signed integer: DuckBignum { magnitude: Vec<u8>, is_negative: bool }, where magnitude is the absolute value in little-endian byte order.

See also