Skip to main content

reddb_server/wire/
protocol.rs

1//! Server-side adapter for the legacy RedDB binary protocol.
2//!
3//! The byte-level contract lives in `reddb-wire::legacy`. This module
4//! only converts between protocol `WireValue` and engine `Value`.
5
6use std::convert::TryFrom;
7
8use crate::storage::schema::Value;
9use reddb_wire::legacy::WireValue;
10
11impl From<&Value> for WireValue {
12    fn from(value: &Value) -> Self {
13        match value {
14            Value::Null => WireValue::Null,
15            Value::Integer(n) => WireValue::I64(*n),
16            Value::UnsignedInteger(n) => WireValue::U64(*n),
17            Value::Float(f) => WireValue::F64(*f),
18            Value::Text(s) => WireValue::Text(s.to_string()),
19            Value::Blob(bytes) => WireValue::Bytes(bytes.clone()),
20            Value::Boolean(b) => WireValue::Bool(*b),
21            Value::Timestamp(t) => WireValue::Timestamp(*t as u64),
22            _ => WireValue::Null,
23        }
24    }
25}
26
27impl From<Value> for WireValue {
28    fn from(value: Value) -> Self {
29        match value {
30            Value::Null => WireValue::Null,
31            Value::Integer(n) => WireValue::I64(n),
32            Value::UnsignedInteger(n) => WireValue::U64(n),
33            Value::Float(f) => WireValue::F64(f),
34            Value::Text(s) => WireValue::Text(s.to_string()),
35            Value::Blob(bytes) => WireValue::Bytes(bytes),
36            Value::Boolean(b) => WireValue::Bool(b),
37            Value::Timestamp(t) => WireValue::Timestamp(t as u64),
38            _ => WireValue::Null,
39        }
40    }
41}
42
43impl TryFrom<WireValue> for Value {
44    type Error = &'static str;
45
46    fn try_from(value: WireValue) -> Result<Self, Self::Error> {
47        match value {
48            WireValue::Null => Ok(Value::Null),
49            WireValue::I64(n) => Ok(Value::Integer(n)),
50            WireValue::U64(n) => Ok(Value::UnsignedInteger(n)),
51            WireValue::F64(f) => Ok(Value::Float(f)),
52            WireValue::Text(s) => Ok(Value::text(s)),
53            WireValue::Bool(b) => Ok(Value::Boolean(b)),
54            WireValue::Bytes(bytes) => Ok(Value::Blob(bytes)),
55            WireValue::Timestamp(t) => {
56                let timestamp = i64::try_from(t).map_err(|_| "timestamp exceeds i64 range")?;
57                Ok(Value::Timestamp(timestamp))
58            }
59        }
60    }
61}
62
63#[inline]
64pub fn encode_value(buf: &mut Vec<u8>, value: &Value) {
65    reddb_wire::legacy::encode_value(buf, &WireValue::from(value));
66}
67
68#[inline]
69pub fn decode_value(data: &[u8], pos: &mut usize) -> Value {
70    try_decode_value(data, pos).unwrap_or(Value::Null)
71}
72
73#[inline]
74pub fn try_decode_value(data: &[u8], pos: &mut usize) -> Result<Value, &'static str> {
75    let value = reddb_wire::legacy::try_decode_value(data, pos)?;
76    Value::try_from(value)
77}