diff --git a/juniper/src/integrations/bson.rs b/juniper/src/integrations/bson.rs new file mode 100644 index 00000000..dcf3be39 --- /dev/null +++ b/juniper/src/integrations/bson.rs @@ -0,0 +1,84 @@ +use bson::{oid::ObjectId, UtcDateTime}; +use chrono::prelude::*; + +use crate::{ + parser::{ParseError, ScalarToken, Token}, + value::ParseScalarResult, + Value, +}; + +graphql_scalar!(ObjectId where Scalar = { + description: "ObjectId" + + resolve(&self) -> Value { + Value::scalar(self.to_hex()) + } + + from_input_value(v: &InputValue) -> Option { + v.as_string_value() + .and_then(|s| ObjectId::with_string(s).ok()) + } + + from_str<'a>(value: ScalarToken<'a>) -> ParseScalarResult<'a, S> { + if let ScalarToken::String(value) = value { + Ok(S::from(value.to_owned())) + } else { + Err(ParseError::UnexpectedToken(Token::Scalar(value))) + } + } +}); + +graphql_scalar!(UtcDateTime where Scalar = { + description: "UtcDateTime" + + resolve(&self) -> Value { + Value::scalar((*self).to_rfc3339()) + } + + from_input_value(v: &InputValue) -> Option { + v.as_string_value() + .and_then(|s| (s.parse::>().ok())) + .map(|d| UtcDateTime(d)) + } + + from_str<'a>(value: ScalarToken<'a>) -> ParseScalarResult<'a, S> { + if let ScalarToken::String(value) = value { + Ok(S::from(value.to_owned())) + } else { + Err(ParseError::UnexpectedToken(Token::Scalar(value))) + } + } +}); + +#[cfg(test)] +mod test { + use crate::{value::DefaultScalarValue, InputValue}; + use bson::{oid::ObjectId, UtcDateTime}; + use chrono::prelude::*; + + #[test] + fn objectid_from_input_value() { + let raw = "53e37d08776f724e42000000"; + let input: InputValue = InputValue::scalar(raw.to_string()); + + let parsed: ObjectId = crate::FromInputValue::from_input_value(&input).unwrap(); + let id = ObjectId::with_string(raw).unwrap(); + + assert_eq!(parsed, id); + } + + #[test] + fn utcdatetime_from_input_value() { + let raw = "2020-03-23T17:38:32.446+00:00"; + let input: InputValue = InputValue::scalar(raw.to_string()); + + let parsed: UtcDateTime = crate::FromInputValue::from_input_value(&input).unwrap(); + let date_time = UtcDateTime( + DateTime::parse_from_rfc3339(raw) + .unwrap() + .with_timezone(&Utc), + ); + + assert_eq!(parsed, date_time); + } +} diff --git a/juniper/src/integrations/mod.rs b/juniper/src/integrations/mod.rs index 7be248a9..f285a3b5 100644 --- a/juniper/src/integrations/mod.rs +++ b/juniper/src/integrations/mod.rs @@ -16,4 +16,4 @@ pub mod uuid; #[cfg(feature = "bson")] /// GraphQL support for [bson](https://github.com/mongodb/bson-rust) types. -pub mod objectid; +pub mod bson; diff --git a/juniper/src/integrations/objectid.rs b/juniper/src/integrations/objectid.rs deleted file mode 100644 index cea59d72..00000000 --- a/juniper/src/integrations/objectid.rs +++ /dev/null @@ -1,45 +0,0 @@ -use bson::oid::ObjectId; - -use crate::{ - parser::{ParseError, ScalarToken, Token}, - value::ParseScalarResult, - Value, -}; - -graphql_scalar!(ObjectId where Scalar = { - description: "ObjectId" - - resolve(&self) -> Value { - Value::scalar(self.to_hex()) - } - - from_input_value(v: &InputValue) -> Option { - v.as_string_value() - .and_then(|s| ObjectId::with_string(s).ok()) - } - - from_str<'a>(value: ScalarToken<'a>) -> ParseScalarResult<'a, S> { - if let ScalarToken::String(value) = value { - Ok(S::from(value.to_owned())) - } else { - Err(ParseError::UnexpectedToken(Token::Scalar(value))) - } - } -}); - -#[cfg(test)] -mod test { - use crate::{value::DefaultScalarValue, InputValue}; - use bson::oid::ObjectId; - - #[test] - fn objectid_from_input_value() { - let raw = "53e37d08776f724e42000000"; - let input: InputValue = InputValue::scalar(raw.to_string()); - - let parsed: ObjectId = crate::FromInputValue::from_input_value(&input).unwrap(); - let id = ObjectId::with_string(raw).unwrap(); - - assert_eq!(parsed, id); - } -}