Repository: near/borsh-rs
Pull request #100 (2022-08-03 13:29:23)

feat: impl ser/de and schema for `(T,)`
Not sure if unary tuples were left out on purpose, but seems sensible to me to support them


Patch:
diff --git a/borsh/src/de/mod.rs b/borsh/src/de/mod.rs
index 208d59a1..f4b2d940 100644
--- a/borsh/src/de/mod.rs
+++ b/borsh/src/de/mod.rs
@@ -588,7 +588,7 @@ impl BorshDeserialize for () {
 
 macro_rules! impl_tuple {
     ($($name:ident)+) => {
-      impl<$($name),+> BorshDeserialize for ($($name),+)
+      impl<$($name),+> BorshDeserialize for ($($name,)+)
       where $($name: BorshDeserialize,)+
       {
         #[inline]
@@ -600,6 +600,7 @@ macro_rules! impl_tuple {
     };
 }
 
+impl_tuple!(T0);
 impl_tuple!(T0 T1);
 impl_tuple!(T0 T1 T2);
 impl_tuple!(T0 T1 T2 T3);
diff --git a/borsh/src/schema.rs b/borsh/src/schema.rs
index f0303d0e..8c6bcf71 100644
--- a/borsh/src/schema.rs
+++ b/borsh/src/schema.rs
@@ -142,7 +142,7 @@ macro_rules! impl_for_primitives {
     };
 }
 
-impl_for_primitives!(bool char f32 f64 i8 i16 i32 i64 i128 u8 u16 u32 u64 u128);
+impl_for_primitives!(bool f32 f64 i8 i16 i32 i64 i128 u8 u16 u32 u64 u128);
 impl_for_renamed_primitives!(String: string);
 impl_for_renamed_primitives!(str: string);
 impl_for_renamed_primitives!(isize: i64);
@@ -303,7 +303,7 @@ where
 
 macro_rules! impl_tuple {
     ($($name:ident),+) => {
-    impl<$($name),+> BorshSchema for ($($name),+)
+    impl<$($name),+> BorshSchema for ($($name,)+)
     where
         $($name: BorshSchema),+
     {
@@ -325,6 +325,7 @@ macro_rules! impl_tuple {
     };
 }
 
+impl_tuple!(T0);
 impl_tuple!(T0, T1);
 impl_tuple!(T0, T1, T2);
 impl_tuple!(T0, T1, T2, T3);
diff --git a/borsh/src/ser/mod.rs b/borsh/src/ser/mod.rs
index f284a1f7..b3244c00 100644
--- a/borsh/src/ser/mod.rs
+++ b/borsh/src/ser/mod.rs
@@ -511,7 +511,7 @@ impl BorshSerialize for () {
 
 macro_rules! impl_tuple {
     ($($idx:tt $name:ident)+) => {
-      impl<$($name),+> BorshSerialize for ($($name),+)
+      impl<$($name),+> BorshSerialize for ($($name,)+)
       where $($name: BorshSerialize,)+
       {
         #[inline]
@@ -523,6 +523,7 @@ macro_rules! impl_tuple {
     };
 }
 
+impl_tuple!(0 T0);
 impl_tuple!(0 T0 1 T1);
 impl_tuple!(0 T0 1 T1 2 T2);
 impl_tuple!(0 T0 1 T1 2 T2 3 T3);


Test patch:
diff --git a/borsh/tests/test_schema_tuple.rs b/borsh/tests/test_schema_tuple.rs
new file mode 100644
index 00000000..c5e6367a
--- /dev/null
+++ b/borsh/tests/test_schema_tuple.rs
@@ -0,0 +1,28 @@
+use borsh::maybestd::collections::HashMap;
+use borsh::schema::*;
+
+macro_rules! map(
+    () => { HashMap::new() };
+    { $($key:expr => $value:expr),+ } => {
+        {
+            let mut m = HashMap::new();
+            $(
+                m.insert($key.to_string(), $value);
+            )+
+            m
+        }
+     };
+);
+
+#[test]
+fn test_unary_tuple_schema() {
+    assert_eq!("Tuple<bool>", <(bool,)>::declaration());
+    let mut defs = Default::default();
+    <(bool,)>::add_definitions_recursively(&mut defs);
+    assert_eq!(
+        map! {
+        "Tuple<bool>" => Definition::Tuple { elements: vec!["bool".to_string()] }
+        },
+        defs
+    );
+}
diff --git a/borsh/tests/test_tuple.rs b/borsh/tests/test_tuple.rs
new file mode 100644
index 00000000..c629dcfc
--- /dev/null
+++ b/borsh/tests/test_tuple.rs
@@ -0,0 +1,9 @@
+use borsh::{BorshDeserialize, BorshSerialize};
+
+#[test]
+fn test_unary_tuple() {
+    let expected = (true,);
+    let buf = expected.try_to_vec().unwrap();
+    let actual = <(bool,)>::try_from_slice(&buf).expect("failed to deserialize");
+    assert_eq!(actual, expected);
+}