Skip to content

Commit

Permalink
Merge pull request #63 from lebai-robotics/wrappers
Browse files Browse the repository at this point in the history
feat: Correct Serialization of google::protobuf::*Value Types
  • Loading branch information
kodiakhq[bot] authored Aug 23, 2022
2 parents 7ffb38b + ac8778a commit 1e746f9
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 0 deletions.
47 changes: 47 additions & 0 deletions pbjson-test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,53 @@ mod tests {
use pbjson_types::{Duration, Timestamp};
use test::syntax3::*;

#[test]
fn test_double_value() {
use pbjson_types::DoubleValue;

let null: Option<DoubleValue> = None;
let encoded = serde_json::to_string(&null).unwrap();
assert_eq!(encoded, "null");
let decoded: Option<DoubleValue> = serde_json::from_str(&encoded).unwrap();
assert_eq!(decoded, null);

let zero: Option<DoubleValue> = Some(DoubleValue { value: 0.0 });
let encoded = serde_json::to_string(&zero).unwrap();
assert_eq!(encoded, "0.0");
let decoded: Option<DoubleValue> = serde_json::from_str(&encoded).unwrap();
assert_eq!(decoded, zero);

let one: Option<DoubleValue> = Some(1.0.into());
let encoded = serde_json::to_string(&one).unwrap();
assert_eq!(encoded, "1.0");
let decoded: Option<DoubleValue> = serde_json::from_str(&encoded).unwrap();
assert_eq!(decoded, one);
}
#[test]
fn test_string_value() {
use pbjson_types::StringValue;

let null: Option<StringValue> = None;
let encoded = serde_json::to_string(&null).unwrap();
assert_eq!(encoded, "null");
let decoded: Option<StringValue> = serde_json::from_str(&encoded).unwrap();
assert_eq!(decoded, null);

let zero: Option<StringValue> = Some(StringValue {
value: String::new(),
});
let encoded = serde_json::to_string(&zero).unwrap();
assert_eq!(encoded, "\"\"");
let decoded: Option<StringValue> = serde_json::from_str(&encoded).unwrap();
assert_eq!(decoded, zero);

let one: Option<StringValue> = Some(String::from("1").into());
let encoded = serde_json::to_string(&one).unwrap();
assert_eq!(encoded, "\"1\"");
let decoded: Option<StringValue> = serde_json::from_str(&encoded).unwrap();
assert_eq!(decoded, one);
}

#[test]
#[cfg(not(feature = "ignore-unknown-fields"))]
fn test_unknown_field_error() {
Expand Down
8 changes: 8 additions & 0 deletions pbjson-types/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ fn main() -> Result<()> {
".google.protobuf.Struct",
".google.protobuf.ListValue",
".google.protobuf.NullValue",
".google.protobuf.BoolValue",
".google.protobuf.DoubleValue",
".google.protobuf.FloatValue",
".google.protobuf.Int32Value",
".google.protobuf.Int64Value",
".google.protobuf.StringValue",
".google.protobuf.UInt32Value",
".google.protobuf.UInt64Value",
])
.build(&[".google"])?;

Expand Down
1 change: 1 addition & 0 deletions pbjson-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,6 @@ mod null_value;
mod r#struct;
mod timestamp;
pub mod value;
mod wrappers;

pub use pb::google::protobuf::*;
49 changes: 49 additions & 0 deletions pbjson-types/src/wrappers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
macro_rules! serde_scalar_value {
($typ: ty) => {
impl serde::Serialize for $typ {
fn serialize<S>(&self, ser: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.value.serialize(ser)
}
}
impl<'de> serde::Deserialize<'de> for $typ {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let value = serde::Deserialize::deserialize(deserializer)?;
Ok(Self { value })
}
}
};
}

macro_rules! convert_scalar_value {
($scalar: ty, $typ: ty) => {
impl From<$scalar> for $typ {
fn from(value: $scalar) -> Self {
Self { value }
}
}
};
}

serde_scalar_value!(crate::BoolValue);
serde_scalar_value!(crate::DoubleValue);
serde_scalar_value!(crate::FloatValue);
serde_scalar_value!(crate::Int32Value);
serde_scalar_value!(crate::Int64Value);
serde_scalar_value!(crate::StringValue);
serde_scalar_value!(crate::UInt32Value);
serde_scalar_value!(crate::UInt64Value);

convert_scalar_value!(bool, crate::BoolValue);
convert_scalar_value!(f64, crate::DoubleValue);
convert_scalar_value!(f32, crate::FloatValue);
convert_scalar_value!(i32, crate::Int32Value);
convert_scalar_value!(i64, crate::Int64Value);
convert_scalar_value!(String, crate::StringValue);
convert_scalar_value!(u32, crate::UInt32Value);
convert_scalar_value!(u64, crate::UInt64Value);

0 comments on commit 1e746f9

Please sign in to comment.