Skip to content

Commit

Permalink
Implement serialize/deserialze for Value (#1158)
Browse files Browse the repository at this point in the history
* Implement serialize/deserialze for Value

* Fix pre-commit
  • Loading branch information
Mallets authored Jun 17, 2024
1 parent 2fccc37 commit 338af96
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 14 deletions.
175 changes: 174 additions & 1 deletion zenoh/src/api/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ use zenoh_buffers::{
ZBuf, ZBufReader, ZBufWriter, ZSlice,
};
use zenoh_codec::{RCodec, WCodec, Zenoh080};
use zenoh_protocol::{core::Parameters, zenoh::ext::AttachmentType};
use zenoh_protocol::{
core::{Encoding as EncodingProto, Parameters},
zenoh::ext::AttachmentType,
};
use zenoh_result::{ZError, ZResult};
#[cfg(feature = "shared-memory")]
use zenoh_shm::{
Expand All @@ -37,6 +40,8 @@ use zenoh_shm::{
ShmBufInner,
};

use super::{encoding::Encoding, value::Value};

/// Trait to encode a type `T` into a [`Value`].
pub trait Serialize<T> {
type Output;
Expand Down Expand Up @@ -1220,6 +1225,174 @@ impl<'s> TryFrom<&'s mut ZBytes> for Parameters<'s> {
}
}

// Encoding
impl Serialize<Encoding> for ZSerde {
type Output = ZBytes;

fn serialize(self, s: Encoding) -> Self::Output {
let e: EncodingProto = s.into();
let codec = Zenoh080::new();
let mut buffer = ZBuf::empty();
let mut writer = buffer.writer();
// SAFETY: we are serializing slices on a ZBuf, so serialization will never
// fail unless we run out of memory. In that case, Rust memory allocator
// will panic before the serializer has any chance to fail.
unsafe {
codec.write(&mut writer, &e).unwrap_unchecked();
}
ZBytes::from(buffer)
}
}

impl From<Encoding> for ZBytes {
fn from(t: Encoding) -> Self {
ZSerde.serialize(t)
}
}

impl Serialize<&Encoding> for ZSerde {
type Output = ZBytes;

fn serialize(self, s: &Encoding) -> Self::Output {
ZSerde.serialize(s.clone())
}
}

impl From<&Encoding> for ZBytes {
fn from(t: &Encoding) -> Self {
ZSerde.serialize(t)
}
}

impl Serialize<&mut Encoding> for ZSerde {
type Output = ZBytes;

fn serialize(self, s: &mut Encoding) -> Self::Output {
ZSerde.serialize(&*s)
}
}

impl From<&mut Encoding> for ZBytes {
fn from(t: &mut Encoding) -> Self {
ZSerde.serialize(t)
}
}

impl<'a> Deserialize<'a, Encoding> for ZSerde {
type Input = &'a ZBytes;
type Error = zenoh_buffers::reader::DidntRead;

fn deserialize(self, v: Self::Input) -> Result<Encoding, Self::Error> {
let codec = Zenoh080::new();
let mut reader = v.0.reader();
let e: EncodingProto = codec.read(&mut reader)?;
Ok(e.into())
}
}

impl TryFrom<ZBytes> for Encoding {
type Error = zenoh_buffers::reader::DidntRead;

fn try_from(value: ZBytes) -> Result<Self, Self::Error> {
ZSerde.deserialize(&value)
}
}

impl TryFrom<&ZBytes> for Encoding {
type Error = zenoh_buffers::reader::DidntRead;

fn try_from(value: &ZBytes) -> Result<Self, Self::Error> {
ZSerde.deserialize(value)
}
}

impl TryFrom<&mut ZBytes> for Encoding {
type Error = zenoh_buffers::reader::DidntRead;

fn try_from(value: &mut ZBytes) -> Result<Self, Self::Error> {
ZSerde.deserialize(&*value)
}
}

// Value
impl Serialize<Value> for ZSerde {
type Output = ZBytes;

fn serialize(self, s: Value) -> Self::Output {
ZSerde.serialize((s.payload(), s.encoding()))
}
}

impl From<Value> for ZBytes {
fn from(t: Value) -> Self {
ZSerde.serialize(t)
}
}

impl Serialize<&Value> for ZSerde {
type Output = ZBytes;

fn serialize(self, s: &Value) -> Self::Output {
ZSerde.serialize(s.clone())
}
}

impl From<&Value> for ZBytes {
fn from(t: &Value) -> Self {
ZSerde.serialize(t)
}
}

impl Serialize<&mut Value> for ZSerde {
type Output = ZBytes;

fn serialize(self, s: &mut Value) -> Self::Output {
ZSerde.serialize(&*s)
}
}

impl From<&mut Value> for ZBytes {
fn from(t: &mut Value) -> Self {
ZSerde.serialize(t)
}
}

impl<'a> Deserialize<'a, Value> for ZSerde {
type Input = &'a ZBytes;
type Error = ZError;

fn deserialize(self, v: Self::Input) -> Result<Value, Self::Error> {
let (payload, encoding) = v
.deserialize::<(ZBytes, Encoding)>()
.map_err(|e| zerror!("{:?}", e))?;
Ok(Value::new(payload, encoding))
}
}

impl TryFrom<ZBytes> for Value {
type Error = ZError;

fn try_from(value: ZBytes) -> Result<Self, Self::Error> {
ZSerde.deserialize(&value)
}
}

impl TryFrom<&ZBytes> for Value {
type Error = ZError;

fn try_from(value: &ZBytes) -> Result<Self, Self::Error> {
ZSerde.deserialize(value)
}
}

impl TryFrom<&mut ZBytes> for Value {
type Error = ZError;

fn try_from(value: &mut ZBytes) -> Result<Self, Self::Error> {
ZSerde.deserialize(&*value)
}
}

// JSON
impl Serialize<serde_json::Value> for ZSerde {
type Output = Result<ZBytes, serde_json::Error>;
Expand Down
2 changes: 1 addition & 1 deletion zenoh/src/api/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1701,7 +1701,7 @@ impl Session {
}
}
(query.callback)(Reply {
result: Err(Value::from("Timeout").into()),
result: Err(Value::new("Timeout", Encoding::ZENOH_STRING).into()),
replier_id: Some(zid.into()),
});
}
Expand Down
12 changes: 0 additions & 12 deletions zenoh/src/api/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,6 @@ impl Value {
}
}

impl<T> From<T> for Value
where
T: Into<ZBytes>,
{
fn from(t: T) -> Self {
Value {
payload: t.into(),
encoding: Encoding::default(),
}
}
}

impl<T> From<Option<T>> for Value
where
T: Into<Value>,
Expand Down

0 comments on commit 338af96

Please sign in to comment.