use crate::envelope::ValueEnvelope;
use crate::error::{Result, WireError};
pub fn encode(envelope: &ValueEnvelope) -> Vec<u8> {
rmp_serde::to_vec_named(envelope).expect("Failed to serialize envelope - this is a bug")
}
pub fn decode(bytes: &[u8]) -> Result<ValueEnvelope> {
rmp_serde::from_slice(bytes).map_err(|e| WireError::DeserializationError(e.to_string()))
}
pub fn to_json(envelope: &ValueEnvelope) -> serde_json::Value {
serde_json::to_value(envelope).expect("Failed to convert to JSON - this is a bug")
}
pub fn from_json(json: &serde_json::Value) -> Result<ValueEnvelope> {
serde_json::from_value(json.clone()).map_err(|e| WireError::DeserializationError(e.to_string()))
}
pub fn to_json_string(envelope: &ValueEnvelope) -> String {
serde_json::to_string(envelope).expect("Failed to serialize to JSON string - this is a bug")
}
pub fn to_json_string_pretty(envelope: &ValueEnvelope) -> String {
serde_json::to_string_pretty(envelope)
.expect("Failed to serialize to JSON string - this is a bug")
}
pub fn from_json_string(s: &str) -> Result<ValueEnvelope> {
serde_json::from_str(s).map_err(|e| WireError::DeserializationError(e.to_string()))
}
pub fn encoded_size(envelope: &ValueEnvelope) -> usize {
encode(envelope).len()
}
pub fn encode_message<T: serde::Serialize>(message: &T) -> Result<Vec<u8>> {
rmp_serde::to_vec_named(message)
.map_err(|e| WireError::DeserializationError(format!("encode failed: {}", e)))
}
pub fn decode_message<'a, T: serde::Deserialize<'a>>(bytes: &'a [u8]) -> Result<T> {
rmp_serde::from_slice(bytes).map_err(|e| WireError::DeserializationError(e.to_string()))
}
#[cfg(test)]
mod tests {
use super::*;
use crate::value::WireValue;
#[test]
fn test_msgpack_roundtrip() {
let env = ValueEnvelope::from_value(WireValue::Number(42.0));
let bytes = encode(&env);
let decoded = decode(&bytes).unwrap();
assert_eq!(env, decoded);
}
#[test]
fn test_json_roundtrip() {
let env = ValueEnvelope::from_value(WireValue::String("hello world".to_string()));
let json = to_json(&env);
let decoded = from_json(&json).unwrap();
assert_eq!(env, decoded);
}
#[test]
fn test_complex_value_roundtrip() {
use crate::value::WireTable;
let table = WireTable {
ipc_bytes: vec![1, 2, 3, 4],
type_name: Some("TestTable".to_string()),
schema_id: Some(1),
row_count: 3,
column_count: 1,
};
let env = ValueEnvelope::from_value(WireValue::Table(table));
let bytes = encode(&env);
let decoded = decode(&bytes).unwrap();
assert_eq!(env, decoded);
let json = to_json(&env);
let decoded = from_json(&json).unwrap();
assert_eq!(env, decoded);
}
#[test]
fn test_json_string_roundtrip() {
let env = ValueEnvelope::timestamp(1704067200000);
let json_str = to_json_string(&env);
let decoded = from_json_string(&json_str).unwrap();
assert_eq!(env, decoded);
}
#[test]
fn test_encoded_size() {
let small = ValueEnvelope::number(1.0);
let large = ValueEnvelope::from_value(WireValue::Array(
(0..1000).map(|i| WireValue::Number(i as f64)).collect(),
));
let small_size = encoded_size(&small);
let large_size = encoded_size(&large);
assert!(small_size < large_size);
assert!(small_size < 2000);
}
#[test]
fn test_invalid_msgpack() {
let result = decode(&[0xFF, 0xFF, 0xFF]);
assert!(result.is_err());
}
#[test]
fn test_invalid_json() {
let json = serde_json::json!({"invalid": "structure"});
let result = from_json(&json);
assert!(result.is_err());
}
}