Skip to content

impl GraphQLScalar for NaiveTime #657

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions juniper/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ default = [
"url",
"uuid",
]
scalar-naivetime = []

[dependencies]
juniper_codegen = { version = "0.14.2", path = "../juniper_codegen" }
Expand Down
75 changes: 75 additions & 0 deletions juniper/src/integrations/chrono.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
| | | precise enough for nanoseconds. |
| | | Values will be truncated to microsecond |
| | | resolution. |
| `NaiveTime` | H:M:S | Optional. Use the `scalar-naivetime` |
| | | feature. |

*/
#![allow(clippy::needless_lifetimes)]
Expand Down Expand Up @@ -99,6 +101,30 @@ where
}
}

#[cfg(feature = "scalar-naivetime")]
#[crate::graphql_scalar_internal(description = "NaiveTime")]
impl<S> GraphQLScalar for NaiveTime
where
S: ScalarValue,
{
fn resolve(&self) -> Value {
Value::scalar(self.format("%H:%M:%S").to_string())
}

fn from_input_value(v: &InputValue) -> Option<NaiveTime> {
v.as_string_value()
.and_then(|s| NaiveTime::parse_from_str(s, "%H:%M:%S").ok())
}

fn 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)))
}
}
}

// JSON numbers (i.e. IEEE doubles) are not precise enough for nanosecond
// datetimes. Values will be truncated to microsecond resolution.
#[crate::graphql_scalar_internal(description = "NaiveDateTime")]
Expand Down Expand Up @@ -194,6 +220,20 @@ mod test {
assert_eq!(parsed.day(), d);
}

#[test]
#[cfg(feature = "scalar-naivetime")]
fn naivetime_from_input_value() {
let input: crate::InputValue<DefaultScalarValue>;
input = InputValue::scalar("21:12:19".to_string());
let [h, m, s] = [21, 12, 19];
let parsed: NaiveTime = crate::FromInputValue::from_input_value(&input).unwrap();
let expected = NaiveTime::from_hms(h, m, s);
assert_eq!(parsed, expected);
assert_eq!(parsed.hour(), h);
assert_eq!(parsed.minute(), m);
assert_eq!(parsed.second(), s);
}

#[test]
fn naivedatetime_from_input_value() {
let raw = 1_000_000_000_f64;
Expand Down Expand Up @@ -223,6 +263,27 @@ mod integration_test {
struct Root;

#[crate::graphql_object_internal]
#[cfg(feature = "scalar-naivetime")]
impl Root {
fn exampleNaiveDate() -> NaiveDate {
NaiveDate::from_ymd(2015, 3, 14)
}
fn exampleNaiveDateTime() -> NaiveDateTime {
NaiveDate::from_ymd(2016, 7, 8).and_hms(9, 10, 11)
}
fn exampleNaiveTime() -> NaiveTime {
NaiveTime::from_hms(16, 7, 8)
}
fn exampleDateTimeFixedOffset() -> DateTime<FixedOffset> {
DateTime::parse_from_rfc3339("1996-12-19T16:39:57-08:00").unwrap()
}
fn exampleDateTimeUtc() -> DateTime<Utc> {
Utc.timestamp(61, 0)
}
}

#[crate::graphql_object_internal]
#[cfg(not(feature = "scalar-naivetime"))]
impl Root {
fn exampleNaiveDate() -> NaiveDate {
NaiveDate::from_ymd(2015, 3, 14)
Expand All @@ -238,6 +299,18 @@ mod integration_test {
}
}

#[cfg(feature = "scalar-naivetime")]
let doc = r#"
{
exampleNaiveDate,
exampleNaiveDateTime,
exampleNaiveTime,
exampleDateTimeFixedOffset,
exampleDateTimeUtc,
}
"#;

#[cfg(not(feature = "scalar-naivetime"))]
let doc = r#"
{
exampleNaiveDate,
Expand Down Expand Up @@ -265,6 +338,8 @@ mod integration_test {
vec![
("exampleNaiveDate", Value::scalar("2015-03-14")),
("exampleNaiveDateTime", Value::scalar(1_467_969_011.0)),
#[cfg(feature = "scalar-naivetime")]
("exampleNaiveTime", Value::scalar("16:07:08")),
(
"exampleDateTimeFixedOffset",
Value::scalar("1996-12-19T16:39:57-08:00"),
Expand Down