Merge pull request #373 from srijs/feat/json-newtype-wrapper
Add Json wrapper type
This commit is contained in:
commit
b190738c23
@ -11,7 +11,7 @@ repository = "https://github.com/sfackler/rust-postgres"
|
||||
"with-chrono-0.4" = ["chrono"]
|
||||
"with-eui48-0.3" = ["eui48"]
|
||||
"with-geo-0.10" = ["geo"]
|
||||
with-serde_json-1 = ["serde_json"]
|
||||
with-serde_json-1 = ["serde", "serde_json"]
|
||||
"with-uuid-0.6" = ["uuid"]
|
||||
|
||||
[dependencies]
|
||||
@ -24,5 +24,6 @@ bit-vec = { version = "0.5", optional = true }
|
||||
chrono = { version = "0.4", optional = true }
|
||||
eui48 = { version = "0.3", optional = true }
|
||||
geo = { version = "0.10", optional = true }
|
||||
serde = { version = "1.0", optional = true }
|
||||
serde_json = { version = "1.0", optional = true }
|
||||
uuid = { version = "0.6", optional = true }
|
||||
|
@ -87,6 +87,9 @@ mod uuid;
|
||||
mod special;
|
||||
mod type_gen;
|
||||
|
||||
#[cfg(feature = "with-serde_json-1")]
|
||||
pub use self::serde_json::Json;
|
||||
|
||||
/// A Postgres type.
|
||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||
pub struct Type(Inner);
|
||||
|
@ -1,13 +1,22 @@
|
||||
extern crate serde;
|
||||
extern crate serde_json;
|
||||
|
||||
use self::serde::{Deserialize, Serialize};
|
||||
use self::serde_json::Value;
|
||||
use std::error::Error;
|
||||
use std::io::{Read, Write};
|
||||
use std::fmt::Debug;
|
||||
use std::io::Read;
|
||||
|
||||
use types::{FromSql, IsNull, ToSql, Type};
|
||||
|
||||
impl<'a> FromSql<'a> for Value {
|
||||
fn from_sql(ty: &Type, mut raw: &[u8]) -> Result<Value, Box<Error + Sync + Send>> {
|
||||
#[derive(Debug)]
|
||||
pub struct Json<T>(pub T);
|
||||
|
||||
impl<'a, T> FromSql<'a> for Json<T>
|
||||
where
|
||||
T: Deserialize<'a>,
|
||||
{
|
||||
fn from_sql(ty: &Type, mut raw: &'a [u8]) -> Result<Json<T>, Box<Error + Sync + Send>> {
|
||||
if *ty == Type::JSONB {
|
||||
let mut b = [0; 1];
|
||||
raw.read_exact(&mut b)?;
|
||||
@ -16,7 +25,33 @@ impl<'a> FromSql<'a> for Value {
|
||||
return Err("unsupported JSONB encoding version".into());
|
||||
}
|
||||
}
|
||||
serde_json::de::from_reader(raw).map_err(Into::into)
|
||||
serde_json::de::from_slice(raw)
|
||||
.map(Json)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
accepts!(JSON, JSONB);
|
||||
}
|
||||
|
||||
impl<T> ToSql for Json<T>
|
||||
where
|
||||
T: Serialize + Debug,
|
||||
{
|
||||
fn to_sql(&self, ty: &Type, out: &mut Vec<u8>) -> Result<IsNull, Box<Error + Sync + Send>> {
|
||||
if *ty == Type::JSONB {
|
||||
out.push(1);
|
||||
}
|
||||
serde_json::ser::to_writer(out, &self.0)?;
|
||||
Ok(IsNull::No)
|
||||
}
|
||||
|
||||
accepts!(JSON, JSONB);
|
||||
to_sql_checked!();
|
||||
}
|
||||
|
||||
impl<'a> FromSql<'a> for Value {
|
||||
fn from_sql(ty: &Type, raw: &[u8]) -> Result<Value, Box<Error + Sync + Send>> {
|
||||
Json::<Value>::from_sql(ty, raw).map(|json| json.0)
|
||||
}
|
||||
|
||||
accepts!(JSON, JSONB);
|
||||
@ -24,11 +59,7 @@ impl<'a> FromSql<'a> for Value {
|
||||
|
||||
impl ToSql for Value {
|
||||
fn to_sql(&self, ty: &Type, out: &mut Vec<u8>) -> Result<IsNull, Box<Error + Sync + Send>> {
|
||||
if *ty == Type::JSONB {
|
||||
out.push(1);
|
||||
}
|
||||
write!(out, "{}", self)?;
|
||||
Ok(IsNull::No)
|
||||
Json(self).to_sql(ty, out)
|
||||
}
|
||||
|
||||
accepts!(JSON, JSONB);
|
||||
|
Loading…
Reference in New Issue
Block a user