Skip to content

Instantly share code, notes, and snippets.

@tqwewe
Created February 7, 2021 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tqwewe/67beafbd30986d4bd02eca0c9b241aef to your computer and use it in GitHub Desktop.
Save tqwewe/67beafbd30986d4bd02eca0c9b241aef to your computer and use it in GitHub Desktop.
Rust Postgres Diesel Timestamptz support with async-graphql
use std::io::Write;
use async_graphql::{InputValueError, InputValueResult, Scalar, ScalarType, Value};
use diesel::{
deserialize,
pg::Pg,
serialize::{self, Output},
sql_types::{self, Timestamp, Timestamptz},
types::{FromSql, ToSql},
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, FromSqlRow, AsExpression)]
#[sql_type = "Timestamp"]
#[sql_type = "Timestamptz"]
/// Timestamps are represented in Postgres as a 64 bit signed integer representing the number of
/// microseconds since January 1st 2000. This struct is a dumb wrapper type, meant only to indicate
/// the integer's meaning.
pub struct GqlTimestamptz(pub i64);
#[Scalar]
impl ScalarType for GqlTimestamptz {
fn parse(value: Value) -> InputValueResult<Self> {
if let Value::String(value) = &value {
// Parse the integer value
Ok(value.parse().map(GqlTimestamptz)?)
} else {
// If the type does not match
Err(InputValueError::expected_type(value))
}
}
fn to_value(&self) -> Value {
Value::Number(self.0.into())
}
}
impl ToSql<sql_types::Timestamp, Pg> for GqlTimestamptz {
fn to_sql<W: Write>(&self, out: &mut Output<W, Pg>) -> serialize::Result {
ToSql::<sql_types::BigInt, Pg>::to_sql(&self.0, out)
}
}
impl FromSql<sql_types::Timestamp, Pg> for GqlTimestamptz {
fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
FromSql::<sql_types::BigInt, Pg>::from_sql(bytes).map(GqlTimestamptz)
}
}
impl ToSql<sql_types::Timestamptz, Pg> for GqlTimestamptz {
fn to_sql<W: Write>(&self, out: &mut Output<W, Pg>) -> serialize::Result {
ToSql::<sql_types::Timestamp, Pg>::to_sql(self, out)
}
}
impl FromSql<sql_types::Timestamptz, Pg> for GqlTimestamptz {
fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
FromSql::<sql_types::Timestamp, Pg>::from_sql(bytes)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment