From 7fbbb6438d499f6f5a2b6dfc6d0d28305baa0a02 Mon Sep 17 00:00:00 2001 From: Daniel Dulaney Date: Sun, 22 Sep 2019 23:51:52 -0400 Subject: [PATCH] Implement Bindable for Option Option is generally used to represent either a T or a null value. In SQLite, it makes sense to model this as either a regular T binding (when the option is Some) or a regular NULL binding (when the option is None). This commit implements Bindable for any Option where T is already Bindable, allowing those Options to be used directly with statements, filling in NULL where needed. No new unsafe code is needed. Tests are included. --- src/statement.rs | 11 +++++++++++ tests/lib.rs | 22 ++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/statement.rs b/src/statement.rs index 7b80f02..3e65b54 100644 --- a/src/statement.rs +++ b/src/statement.rs @@ -229,6 +229,17 @@ impl Bindable for () { } } +impl Bindable for Option { + #[inline] + fn bind(self, statement: &mut Statement, i: usize) -> Result<()> { + debug_assert!(i > 0, "the indexing starts from 1"); + match self { + Some(inner) => inner.bind(statement, i), + None => ().bind(statement, i), + } + } +} + impl Readable for Value { fn read(statement: &Statement, i: usize) -> Result { Ok(match statement.kind(i) { diff --git a/tests/lib.rs b/tests/lib.rs index 28827d5..27c5750 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -186,6 +186,28 @@ fn statement_bind() { assert_eq!(ok!(statement.next()), State::Done); } +#[test] +fn statement_optional_bind() { + let connection = setup_users(":memory:"); + let statement = "INSERT INTO users VALUES (?, ?, ?, ?)"; + let mut statement = ok!(connection.prepare(statement)); + + ok!(statement.bind(1, None::)); + ok!(statement.bind(2, None::<&str>)); + ok!(statement.bind(3, None::)); + ok!(statement.bind(4, None::<&[u8]>)); + assert_eq!(ok!(statement.next()), State::Done); + + let statement = "INSERT INTO users VALUES (?, ?, ?, ?)"; + let mut statement = ok!(connection.prepare(statement)); + + ok!(statement.bind(1, Some(2i64))); + ok!(statement.bind(2, Some("Bob"))); + ok!(statement.bind(3, Some(69.42))); + ok!(statement.bind(4, Some(&[0x69u8, 0x42u8][..]))); + assert_eq!(ok!(statement.next()), State::Done); +} + #[test] fn statement_count() { let connection = setup_users(":memory:");