use async_graphql::*; use sqlx::{ postgres::{PgArgumentBuffer, PgHasArrayType, PgTypeInfo, PgValueRef}, Decode, Encode, Postgres, Type, }; use ulid::Ulid as UlidPrimitive; pub type Time = chrono::DateTime; /// The ID scalar type represents a unique identifier, often used to refetch an object or as key for a cache. /// The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. /// When expected as an input type, any string (such as "4") or integer (such as 4) input value will be accepted as an ID. pub type Id = uuid::Uuid; #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct Ulid(pub UlidPrimitive); #[Scalar] impl ScalarType for Ulid { fn parse(value: Value) -> InputValueResult { match value { Value::String(s) => { let ulid = UlidPrimitive::from_string(&s).map_err(InputValueError::custom)?; Ok(Ulid(ulid)) } _ => Err(InputValueError::expected_type(value)), } } fn to_value(&self) -> Value { Value::String(self.0.to_string()) } } impl Type for Ulid { fn type_info() -> PgTypeInfo { >::type_info() } fn compatible(ty: &PgTypeInfo) -> bool { >::compatible(ty) } } impl<'r> Decode<'r, Postgres> for Ulid { fn decode(value: PgValueRef<'r>) -> Result> { let s = >::decode(value)?; Ok(Ulid(UlidPrimitive::from_string(s.trim())?)) } } impl<'q> Encode<'q, Postgres> for Ulid { fn encode_by_ref( &self, buf: &mut PgArgumentBuffer, ) -> Result> { >::encode(self.0.to_string(), buf) } } impl PgHasArrayType for Ulid { fn array_type_info() -> PgTypeInfo { ::array_type_info() } }