Skip to content

Commit b190738

Browse files
authored
Merge pull request sfackler#373 from srijs/feat/json-newtype-wrapper
Add Json wrapper type
2 parents 12546ec + afce0b7 commit b190738

File tree

3 files changed

+42
-7
lines changed

3 files changed

+42
-7
lines changed

postgres-shared/Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ repository = "https://github.com/sfackler/rust-postgres"
1111
"with-chrono-0.4" = ["chrono"]
1212
"with-eui48-0.3" = ["eui48"]
1313
"with-geo-0.10" = ["geo"]
14-
with-serde_json-1 = ["serde_json"]
14+
with-serde_json-1 = ["serde", "serde_json"]
1515
"with-uuid-0.6" = ["uuid"]
1616

1717
[dependencies]
@@ -24,5 +24,6 @@ bit-vec = { version = "0.5", optional = true }
2424
chrono = { version = "0.4", optional = true }
2525
eui48 = { version = "0.3", optional = true }
2626
geo = { version = "0.10", optional = true }
27+
serde = { version = "1.0", optional = true }
2728
serde_json = { version = "1.0", optional = true }
2829
uuid = { version = "0.6", optional = true }

postgres-shared/src/types/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ mod uuid;
8787
mod special;
8888
mod type_gen;
8989

90+
#[cfg(feature = "with-serde_json-1")]
91+
pub use self::serde_json::Json;
92+
9093
/// A Postgres type.
9194
#[derive(PartialEq, Eq, Clone, Debug)]
9295
pub struct Type(Inner);
+37-6
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
1+
extern crate serde;
12
extern crate serde_json;
23

4+
use self::serde::{Deserialize, Serialize};
35
use self::serde_json::Value;
46
use std::error::Error;
5-
use std::io::{Read, Write};
7+
use std::fmt::Debug;
8+
use std::io::Read;
69

710
use types::{FromSql, IsNull, ToSql, Type};
811

9-
impl<'a> FromSql<'a> for Value {
10-
fn from_sql(ty: &Type, mut raw: &[u8]) -> Result<Value, Box<Error + Sync + Send>> {
12+
#[derive(Debug)]
13+
pub struct Json<T>(pub T);
14+
15+
impl<'a, T> FromSql<'a> for Json<T>
16+
where
17+
T: Deserialize<'a>,
18+
{
19+
fn from_sql(ty: &Type, mut raw: &'a [u8]) -> Result<Json<T>, Box<Error + Sync + Send>> {
1120
if *ty == Type::JSONB {
1221
let mut b = [0; 1];
1322
raw.read_exact(&mut b)?;
@@ -16,21 +25,43 @@ impl<'a> FromSql<'a> for Value {
1625
return Err("unsupported JSONB encoding version".into());
1726
}
1827
}
19-
serde_json::de::from_reader(raw).map_err(Into::into)
28+
serde_json::de::from_slice(raw)
29+
.map(Json)
30+
.map_err(Into::into)
2031
}
2132

2233
accepts!(JSON, JSONB);
2334
}
2435

25-
impl ToSql for Value {
36+
impl<T> ToSql for Json<T>
37+
where
38+
T: Serialize + Debug,
39+
{
2640
fn to_sql(&self, ty: &Type, out: &mut Vec<u8>) -> Result<IsNull, Box<Error + Sync + Send>> {
2741
if *ty == Type::JSONB {
2842
out.push(1);
2943
}
30-
write!(out, "{}", self)?;
44+
serde_json::ser::to_writer(out, &self.0)?;
3145
Ok(IsNull::No)
3246
}
3347

3448
accepts!(JSON, JSONB);
3549
to_sql_checked!();
3650
}
51+
52+
impl<'a> FromSql<'a> for Value {
53+
fn from_sql(ty: &Type, raw: &[u8]) -> Result<Value, Box<Error + Sync + Send>> {
54+
Json::<Value>::from_sql(ty, raw).map(|json| json.0)
55+
}
56+
57+
accepts!(JSON, JSONB);
58+
}
59+
60+
impl ToSql for Value {
61+
fn to_sql(&self, ty: &Type, out: &mut Vec<u8>) -> Result<IsNull, Box<Error + Sync + Send>> {
62+
Json(self).to_sql(ty, out)
63+
}
64+
65+
accepts!(JSON, JSONB);
66+
to_sql_checked!();
67+
}

0 commit comments

Comments
 (0)