Encode a fixed-size value into the buffer at the given position. Handles both native Value types and SQL coercion sources.
(dst: &mut [u8], col_type: &ColumnType, value: &Value)
| 202 | /// |
| 203 | /// Handles both native Value types and SQL coercion sources. |
| 204 | fn encode_fixed(dst: &mut [u8], col_type: &ColumnType, value: &Value) { |
| 205 | match (col_type, value) { |
| 206 | // Int64: native. |
| 207 | (ColumnType::Int64, Value::Integer(v)) => { |
| 208 | dst[..8].copy_from_slice(&v.to_le_bytes()); |
| 209 | } |
| 210 | // Float64: native + Int64→Float64 coercion. |
| 211 | (ColumnType::Float64, Value::Float(v)) => { |
| 212 | dst[..8].copy_from_slice(&v.to_le_bytes()); |
| 213 | } |
| 214 | (ColumnType::Float64, Value::Integer(v)) => { |
| 215 | dst[..8].copy_from_slice(&(*v as f64).to_le_bytes()); |
| 216 | } |
| 217 | // Bool: native. |
| 218 | (ColumnType::Bool, Value::Bool(v)) => { |
| 219 | dst[0] = *v as u8; |
| 220 | } |
| 221 | // Timestamp (naive): NaiveDateTime + Integer (micros) + String (ISO 8601 parse). |
| 222 | (ColumnType::Timestamp, Value::NaiveDateTime(dt)) => { |
| 223 | dst[..8].copy_from_slice(&dt.micros.to_le_bytes()); |
| 224 | } |
| 225 | (ColumnType::Timestamp, Value::Integer(micros)) => { |
| 226 | dst[..8].copy_from_slice(µs.to_le_bytes()); |
| 227 | } |
| 228 | (ColumnType::Timestamp, Value::String(s)) => { |
| 229 | let micros = nodedb_types::NdbDateTime::parse(s) |
| 230 | .map(|dt| dt.micros) |
| 231 | .unwrap_or(0); |
| 232 | dst[..8].copy_from_slice(µs.to_le_bytes()); |
| 233 | } |
| 234 | // Timestamptz (TZ-aware): DateTime + Integer (micros) + String (ISO 8601 parse). |
| 235 | (ColumnType::Timestamptz, Value::DateTime(dt)) => { |
| 236 | dst[..8].copy_from_slice(&dt.micros.to_le_bytes()); |
| 237 | } |
| 238 | (ColumnType::Timestamptz, Value::Integer(micros)) => { |
| 239 | dst[..8].copy_from_slice(µs.to_le_bytes()); |
| 240 | } |
| 241 | (ColumnType::Timestamptz, Value::String(s)) => { |
| 242 | let micros = nodedb_types::NdbDateTime::parse(s) |
| 243 | .map(|dt| dt.micros) |
| 244 | .unwrap_or(0); |
| 245 | dst[..8].copy_from_slice(µs.to_le_bytes()); |
| 246 | } |
| 247 | // Decimal: native Decimal + String/Float/Integer coercion. |
| 248 | (ColumnType::Decimal { .. }, Value::Decimal(d)) => { |
| 249 | dst[..16].copy_from_slice(&d.serialize()); |
| 250 | } |
| 251 | (ColumnType::Decimal { .. }, Value::String(s)) => { |
| 252 | let d: rust_decimal::Decimal = s.parse().unwrap_or_default(); |
| 253 | dst[..16].copy_from_slice(&d.serialize()); |
| 254 | } |
| 255 | (ColumnType::Decimal { .. }, Value::Float(f)) => { |
| 256 | let d = rust_decimal::Decimal::try_from(*f).unwrap_or_default(); |
| 257 | dst[..16].copy_from_slice(&d.serialize()); |
| 258 | } |
| 259 | (ColumnType::Decimal { .. }, Value::Integer(i)) => { |
| 260 | let d = rust_decimal::Decimal::from(*i); |
| 261 | dst[..16].copy_from_slice(&d.serialize()); |