diff --git a/libsql/src/value.rs b/libsql/src/value.rs index 7d50265eed..be883b9dc1 100644 --- a/libsql/src/value.rs +++ b/libsql/src/value.rs @@ -631,7 +631,7 @@ mod serde_ { serde::forward_to_deserialize_any! { i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string - bytes byte_buf unit_struct newtype_struct seq tuple tuple_struct + bytes byte_buf unit_struct seq tuple tuple_struct map struct identifier ignored_any } @@ -760,6 +760,17 @@ mod serde_ { )), } } + + fn deserialize_newtype_struct( + self, + _name: &'static str, + visitor: V, + ) -> std::result::Result + where + V: Visitor<'de>, + { + visitor.visit_newtype_struct(self) + } } impl<'de, E: de::Error> IntoDeserializer<'de, E> for Value { @@ -792,6 +803,19 @@ mod serde_ { B, } + #[derive(Deserialize, Debug, PartialEq)] + struct MyStringNewType(String); + #[derive(Deserialize, Debug, PartialEq)] + struct MyIntNewType(i64); + #[derive(Deserialize, Debug, PartialEq)] + struct MyFloatNewType(f64); + #[derive(Deserialize, Debug, PartialEq)] + struct MyBoolNewType(bool); + #[derive(Deserialize, Debug, PartialEq)] + struct MyVecNewType(Vec); + #[derive(Deserialize, Debug, PartialEq)] + struct MyOptionNewType(Option); + assert_eq!(de::(Value::Text("A".to_string())), Ok(MyEnum::A)); assert_eq!(de::<()>(Value::Null), Ok(())); assert_eq!(de::(Value::Integer(123)), Ok(123)); @@ -816,6 +840,27 @@ mod serde_ { assert!(de::(Value::Text("C".to_string())).is_err()); assert_eq!(de::<[u8; 2]>(Value::Blob(b"aa".to_vec())), Ok([97, 97])); + + assert_eq!( + de::(Value::Text("abc".to_string())), + Ok(MyStringNewType("abc".to_string())) + ); + assert_eq!( + de::(Value::Integer(123)), + Ok(MyIntNewType(123)) + ); + assert_eq!( + de::(Value::Real(123.4)), + Ok(MyFloatNewType(123.4)) + ); + assert_eq!( + de::(Value::Blob(b"abc".to_vec())), + Ok(MyVecNewType(b"abc".to_vec())) + ); + assert_eq!( + de::(Value::Integer(123)), + Ok(MyOptionNewType(Some(123))) + ); } } } diff --git a/libsql/tests/integration_tests.rs b/libsql/tests/integration_tests.rs index 92d8d358d8..6fb7725aea 100644 --- a/libsql/tests/integration_tests.rs +++ b/libsql/tests/integration_tests.rs @@ -634,11 +634,11 @@ async fn deserialize_row() { let conn = db.connect().unwrap(); let _ = conn .execute( - "CREATE TABLE users (id INTEGER, name TEXT, score REAL, data BLOB, age INTEGER, status TEXT, wrapper TEXT)", + "CREATE TABLE users (id INTEGER, name TEXT, score REAL, data BLOB, age INTEGER, status TEXT, wrapper TEXT, newtype TEXT)", (), ) .await; - conn.execute("INSERT INTO users (id, name, score, data, age, status, wrapper) VALUES (123, 'potato', 42.0, X'deadbeef', NULL, 'Draft', 'Published')", ()) + conn.execute("INSERT INTO users (id, name, score, data, age, status, wrapper, newtype) VALUES (123, 'potato', 42.0, X'deadbeef', NULL, 'Draft', 'Published', 'Newtype')", ()) .await .unwrap(); @@ -654,8 +654,12 @@ async fn deserialize_row() { none: Option<()>, status: Status, wrapper: Wrapper, + newtype: NewType, } + #[derive(Deserialize, Debug, PartialEq)] + struct NewType(String); + #[derive(Deserialize, Debug, PartialEq)] enum Status { Draft, @@ -683,6 +687,7 @@ async fn deserialize_row() { assert_eq!(data.none, None); assert_eq!(data.status, Status::Draft); assert_eq!(data.wrapper, Wrapper(Status::Published)); + assert_eq!(data.newtype, NewType("Newtype".to_string())); } #[tokio::test]