aboutsummaryrefslogtreecommitdiff
path: root/src/types/serde_json.rs
diff options
context:
space:
mode:
authorJoel Galenson <jgalenson@google.com>2020-07-28 13:34:02 -0700
committerJoel Galenson <jgalenson@google.com>2020-07-28 13:34:02 -0700
commit8b0df7ff3a4139db9f9ed71ea9d0bc82eca3eb30 (patch)
treeba5a264b0979e0fa15b1912cde8b9c04bd0e109f /src/types/serde_json.rs
parent26442fd4c4f3e1f469c323e695c4fcd972b150f5 (diff)
downloadrusqlite-8b0df7ff3a4139db9f9ed71ea9d0bc82eca3eb30.tar.gz
Import rusqlite-0.23.1
Change-Id: Id1ca7bcaad7820f463bfcce6945d80fc1d6918f5
Diffstat (limited to 'src/types/serde_json.rs')
-rw-r--r--src/types/serde_json.rs60
1 files changed, 60 insertions, 0 deletions
diff --git a/src/types/serde_json.rs b/src/types/serde_json.rs
new file mode 100644
index 0000000..abaecda
--- /dev/null
+++ b/src/types/serde_json.rs
@@ -0,0 +1,60 @@
+//! `ToSql` and `FromSql` implementation for JSON `Value`.
+
+use serde_json::Value;
+
+use crate::types::{FromSql, FromSqlError, FromSqlResult, ToSql, ToSqlOutput, ValueRef};
+use crate::Result;
+
+/// Serialize JSON `Value` to text.
+impl ToSql for Value {
+ fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
+ Ok(ToSqlOutput::from(serde_json::to_string(self).unwrap()))
+ }
+}
+
+/// Deserialize text/blob to JSON `Value`.
+impl FromSql for Value {
+ fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
+ match value {
+ ValueRef::Text(s) => serde_json::from_slice(s),
+ ValueRef::Blob(b) => serde_json::from_slice(b),
+ _ => return Err(FromSqlError::InvalidType),
+ }
+ .map_err(|err| FromSqlError::Other(Box::new(err)))
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use crate::types::ToSql;
+ use crate::{Connection, NO_PARAMS};
+
+ fn checked_memory_handle() -> Connection {
+ let db = Connection::open_in_memory().unwrap();
+ db.execute_batch("CREATE TABLE foo (t TEXT, b BLOB)")
+ .unwrap();
+ db
+ }
+
+ #[test]
+ fn test_json_value() {
+ let db = checked_memory_handle();
+
+ let json = r#"{"foo": 13, "bar": "baz"}"#;
+ let data: serde_json::Value = serde_json::from_str(json).unwrap();
+ db.execute(
+ "INSERT INTO foo (t, b) VALUES (?, ?)",
+ &[&data as &dyn ToSql, &json.as_bytes()],
+ )
+ .unwrap();
+
+ let t: serde_json::Value = db
+ .query_row("SELECT t FROM foo", NO_PARAMS, |r| r.get(0))
+ .unwrap();
+ assert_eq!(data, t);
+ let b: serde_json::Value = db
+ .query_row("SELECT b FROM foo", NO_PARAMS, |r| r.get(0))
+ .unwrap();
+ assert_eq!(data, b);
+ }
+}