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-chrono-0.4" = ["chrono"]
|
||||||
"with-eui48-0.3" = ["eui48"]
|
"with-eui48-0.3" = ["eui48"]
|
||||||
"with-geo-0.10" = ["geo"]
|
"with-geo-0.10" = ["geo"]
|
||||||
with-serde_json-1 = ["serde_json"]
|
with-serde_json-1 = ["serde", "serde_json"]
|
||||||
"with-uuid-0.6" = ["uuid"]
|
"with-uuid-0.6" = ["uuid"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
@ -24,5 +24,6 @@ bit-vec = { version = "0.5", optional = true }
|
|||||||
chrono = { version = "0.4", optional = true }
|
chrono = { version = "0.4", optional = true }
|
||||||
eui48 = { version = "0.3", optional = true }
|
eui48 = { version = "0.3", optional = true }
|
||||||
geo = { version = "0.10", optional = true }
|
geo = { version = "0.10", optional = true }
|
||||||
|
serde = { version = "1.0", optional = true }
|
||||||
serde_json = { version = "1.0", optional = true }
|
serde_json = { version = "1.0", optional = true }
|
||||||
uuid = { version = "0.6", optional = true }
|
uuid = { version = "0.6", optional = true }
|
||||||
|
@ -87,6 +87,9 @@ mod uuid;
|
|||||||
mod special;
|
mod special;
|
||||||
mod type_gen;
|
mod type_gen;
|
||||||
|
|
||||||
|
#[cfg(feature = "with-serde_json-1")]
|
||||||
|
pub use self::serde_json::Json;
|
||||||
|
|
||||||
/// A Postgres type.
|
/// A Postgres type.
|
||||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||||
pub struct Type(Inner);
|
pub struct Type(Inner);
|
||||||
|
@ -1,13 +1,22 @@
|
|||||||
|
extern crate serde;
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
|
|
||||||
|
use self::serde::{Deserialize, Serialize};
|
||||||
use self::serde_json::Value;
|
use self::serde_json::Value;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::io::{Read, Write};
|
use std::fmt::Debug;
|
||||||
|
use std::io::Read;
|
||||||
|
|
||||||
use types::{FromSql, IsNull, ToSql, Type};
|
use types::{FromSql, IsNull, ToSql, Type};
|
||||||
|
|
||||||
impl<'a> FromSql<'a> for Value {
|
#[derive(Debug)]
|
||||||
fn from_sql(ty: &Type, mut raw: &[u8]) -> Result<Value, Box<Error + Sync + Send>> {
|
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 {
|
if *ty == Type::JSONB {
|
||||||
let mut b = [0; 1];
|
let mut b = [0; 1];
|
||||||
raw.read_exact(&mut b)?;
|
raw.read_exact(&mut b)?;
|
||||||
@ -16,7 +25,33 @@ impl<'a> FromSql<'a> for Value {
|
|||||||
return Err("unsupported JSONB encoding version".into());
|
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);
|
accepts!(JSON, JSONB);
|
||||||
@ -24,11 +59,7 @@ impl<'a> FromSql<'a> for Value {
|
|||||||
|
|
||||||
impl ToSql for Value {
|
impl ToSql for Value {
|
||||||
fn to_sql(&self, ty: &Type, out: &mut Vec<u8>) -> Result<IsNull, Box<Error + Sync + Send>> {
|
fn to_sql(&self, ty: &Type, out: &mut Vec<u8>) -> Result<IsNull, Box<Error + Sync + Send>> {
|
||||||
if *ty == Type::JSONB {
|
Json(self).to_sql(ty, out)
|
||||||
out.push(1);
|
|
||||||
}
|
|
||||||
write!(out, "{}", self)?;
|
|
||||||
Ok(IsNull::No)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
accepts!(JSON, JSONB);
|
accepts!(JSON, JSONB);
|
||||||
|
Loading…
Reference in New Issue
Block a user