From 0f6ddc3871fb6e5ae617468af75062c9d3ac2b35 Mon Sep 17 00:00:00 2001 From: v3xro <175618876+v3xro@users.noreply.github.com> Date: Tue, 30 Jul 2024 17:53:33 +0100 Subject: [PATCH 1/3] fix(bind): allow serialization of Some(_) and None values (as the inner value and NULL respectively) --- src/sql/ser.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/sql/ser.rs b/src/sql/ser.rs index 3120f9e..dbea2b0 100644 --- a/src/sql/ser.rs +++ b/src/sql/ser.rs @@ -86,7 +86,6 @@ impl<'a, W: Write> Serializer for SqlSerializer<'a, W> { unsupported!( serialize_map(Option) -> Result, serialize_bytes(&[u8]), - serialize_none, serialize_unit, serialize_unit_struct(&'static str), ); @@ -141,7 +140,13 @@ impl<'a, W: Write> Serializer for SqlSerializer<'a, W> { #[inline] fn serialize_some(self, _value: &T) -> Result { - Err(SqlSerializerError::Unsupported("serialize_some")) + _value.serialize(self) + } + + #[inline] + fn serialize_none(self) -> std::result::Result { + self.writer.write_str("NULL")?; + Ok(()) } #[inline] From 97b925e918d9eb6c151a4f2c089ca827e96303b3 Mon Sep 17 00:00:00 2001 From: v3xro <175618876+v3xro@users.noreply.github.com> Date: Wed, 31 Jul 2024 12:36:34 +0100 Subject: [PATCH 2/3] chore: add tests --- src/sql/mod.rs | 21 ++++++++++++++------- src/sql/ser.rs | 4 ++-- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/sql/mod.rs b/src/sql/mod.rs index 76ab3ef..edb42e7 100644 --- a/src/sql/mod.rs +++ b/src/sql/mod.rs @@ -184,6 +184,20 @@ mod tests { ); } + #[test] + fn option_as_null() { + let mut sql = SqlBuilder::new("SELECT 1 FROM test WHERE a = ?"); + sql.bind_arg(None::); + assert_eq!(sql.finish().unwrap(), r"SELECT 1 FROM test WHERE a = NULL"); + } + + #[test] + fn option_as_value() { + let mut sql = SqlBuilder::new("SELECT 1 FROM test WHERE a = ?"); + sql.bind_arg(Some(1u32)); + assert_eq!(sql.finish().unwrap(), r"SELECT 1 FROM test WHERE a = 1"); + } + #[test] fn failures() { let mut sql = SqlBuilder::new("SELECT 1"); @@ -191,13 +205,6 @@ mod tests { let err = sql.finish().unwrap_err(); assert!(err.to_string().contains("all arguments are already bound")); - let mut sql = SqlBuilder::new("SELECT ?"); - sql.bind_arg(None::); - let err = sql.finish().unwrap_err(); - assert!(err - .to_string() - .contains("invalid argument: serialize_none is unsupported")); - let mut sql = SqlBuilder::new("SELECT ?fields"); sql.bind_fields::(); let err = sql.finish().unwrap_err(); diff --git a/src/sql/ser.rs b/src/sql/ser.rs index dbea2b0..5ab55d9 100644 --- a/src/sql/ser.rs +++ b/src/sql/ser.rs @@ -345,8 +345,8 @@ mod tests { fn it_fails_on_unsupported() { let mut out = String::new(); assert!(write_arg(&mut out, &std::collections::HashMap::::new()).is_err()); - assert!(write_arg(&mut out, &None::).is_err()); - assert!(write_arg(&mut out, &Some(42)).is_err()); + assert!(write_arg(&mut out, &None::).is_ok()); + assert!(write_arg(&mut out, &Some(42)).is_ok()); assert!(write_arg(&mut out, &()).is_err()); #[derive(Serialize)] From f515d3be523140bb87435a3e7238d511ebeec214 Mon Sep 17 00:00:00 2001 From: v3xro <175618876+v3xro@users.noreply.github.com> Date: Mon, 5 Aug 2024 20:35:44 +0100 Subject: [PATCH 3/3] chore: move test for option into own function --- src/sql/ser.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/sql/ser.rs b/src/sql/ser.rs index 5ab55d9..00ea606 100644 --- a/src/sql/ser.rs +++ b/src/sql/ser.rs @@ -341,12 +341,17 @@ mod tests { assert_eq!(check((42, 43)), "(42,43)"); } + #[test] + fn it_writes_options() { + assert_eq!(check(None::), "NULL"); + assert_eq!(check(Some(32)), "32"); + assert_eq!(check(Some(vec![42, 43])), "[42,43]"); + } + #[test] fn it_fails_on_unsupported() { let mut out = String::new(); assert!(write_arg(&mut out, &std::collections::HashMap::::new()).is_err()); - assert!(write_arg(&mut out, &None::).is_ok()); - assert!(write_arg(&mut out, &Some(42)).is_ok()); assert!(write_arg(&mut out, &()).is_err()); #[derive(Serialize)]