Support chrono-tz::Tz GraphQL scalar (#519)
Co-authored-by: Nirman Gupta <nirmangupta@gmail.com> Co-authored-by: Kai Ren <tyranron@gmail.com>
This commit is contained in:
parent
31d339b3a9
commit
5832b3696d
6 changed files with 90 additions and 2 deletions
|
@ -68,6 +68,7 @@ your Schemas automatically.
|
||||||
- [uuid][uuid]
|
- [uuid][uuid]
|
||||||
- [url][url]
|
- [url][url]
|
||||||
- [chrono][chrono]
|
- [chrono][chrono]
|
||||||
|
- [chrono-tz][chrono-tz]
|
||||||
- [bson][bson]
|
- [bson][bson]
|
||||||
|
|
||||||
### Web Frameworks
|
### Web Frameworks
|
||||||
|
@ -112,5 +113,6 @@ Juniper has not reached 1.0 yet, thus some API instability should be expected.
|
||||||
[uuid]: https://crates.io/crates/uuid
|
[uuid]: https://crates.io/crates/uuid
|
||||||
[url]: https://crates.io/crates/url
|
[url]: https://crates.io/crates/url
|
||||||
[chrono]: https://crates.io/crates/chrono
|
[chrono]: https://crates.io/crates/chrono
|
||||||
|
[chrono-tz]: https://crates.io/crates/chrono-tz
|
||||||
[bson]: https://crates.io/crates/bson
|
[bson]: https://crates.io/crates/bson
|
||||||
[juniper-from-schema]: https://github.com/davidpdrsn/juniper-from-schema
|
[juniper-from-schema]: https://github.com/davidpdrsn/juniper-from-schema
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
- `ParseError`
|
- `ParseError`
|
||||||
- `RuleError`
|
- `RuleError`
|
||||||
|
|
||||||
|
- Support `chrono-tz::Tz` scalar behind a `chrono-tz` feature flag. ([#519](https://github.com/graphql-rust/juniper/pull/519))
|
||||||
|
|
||||||
## Fixes
|
## Fixes
|
||||||
|
|
||||||
- Massively improved the `#[graphql_union]` proc macro. ([#666](https://github.com/graphql-rust/juniper/pull/666)):
|
- Massively improved the `#[graphql_union]` proc macro. ([#666](https://github.com/graphql-rust/juniper/pull/666)):
|
||||||
|
|
|
@ -38,6 +38,7 @@ anyhow = { default-features = false, version = "1.0.32", optional = true }
|
||||||
async-trait = "0.1.39"
|
async-trait = "0.1.39"
|
||||||
bson = { version = "1.0", optional = true }
|
bson = { version = "1.0", optional = true }
|
||||||
chrono = { default-features = false, version = "0.4", optional = true }
|
chrono = { default-features = false, version = "0.4", optional = true }
|
||||||
|
chrono-tz = { version = "0.5", default-features = false, optional = true }
|
||||||
fnv = "1.0.3"
|
fnv = "1.0.3"
|
||||||
futures = { default-features = false, features = ["alloc"], version = "0.3.1" }
|
futures = { default-features = false, features = ["alloc"], version = "0.3.1" }
|
||||||
futures-enum = "0.1.12"
|
futures-enum = "0.1.12"
|
||||||
|
|
80
juniper/src/integrations/chrono_tz.rs
Normal file
80
juniper/src/integrations/chrono_tz.rs
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
//! [`Tz`] (timezone) scalar implementation, represented by its [IANA database][1] name.
|
||||||
|
//!
|
||||||
|
//! [`Tz`]: chrono_tz::Tz
|
||||||
|
//! [1]: http://www.iana.org/time-zones
|
||||||
|
|
||||||
|
use chrono_tz::Tz;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
graphql_scalar,
|
||||||
|
parser::{ParseError, ScalarToken, Token},
|
||||||
|
value::ParseScalarResult,
|
||||||
|
Value,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[graphql_scalar(name = "Tz", description = "Timezone")]
|
||||||
|
impl<S> GraphQLScalar for Tz
|
||||||
|
where
|
||||||
|
S: ScalarValue,
|
||||||
|
{
|
||||||
|
fn resolve(&self) -> Value {
|
||||||
|
Value::scalar(self.name().to_owned())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_input_value(v: &InputValue) -> Option<Tz> {
|
||||||
|
v.as_string_value().and_then(|s| s.parse::<Tz>().ok())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_str<'a>(val: ScalarToken<'a>) -> ParseScalarResult<'a, S> {
|
||||||
|
if let ScalarToken::String(s) = val {
|
||||||
|
Ok(S::from(s.to_owned()))
|
||||||
|
} else {
|
||||||
|
Err(ParseError::UnexpectedToken(Token::Scalar(val)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
mod from_input_value {
|
||||||
|
use chrono_tz::Tz;
|
||||||
|
|
||||||
|
use crate::{DefaultScalarValue, FromInputValue, InputValue};
|
||||||
|
|
||||||
|
fn tz_input_test(raw: &'static str, expected: Option<Tz>) {
|
||||||
|
let input = <InputValue<DefaultScalarValue>>::scalar(raw.to_string());
|
||||||
|
let parsed: Option<Tz> = FromInputValue::from_input_value(&input);
|
||||||
|
|
||||||
|
assert_eq!(parsed, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn europe_zone() {
|
||||||
|
tz_input_test("Europe/London", Some(chrono_tz::Europe::London));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn etc_minus() {
|
||||||
|
tz_input_test("Etc/GMT-3", Some(chrono_tz::Etc::GMTMinus3));
|
||||||
|
}
|
||||||
|
|
||||||
|
mod invalid {
|
||||||
|
use super::tz_input_test;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn forward_slash() {
|
||||||
|
tz_input_test("Abc/Xyz", None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn number() {
|
||||||
|
tz_input_test("8086", None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn no_forward_slash() {
|
||||||
|
tz_input_test("AbcXyz", None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,10 @@ pub mod serde;
|
||||||
/// GraphQL support for [chrono](https://github.com/chronotope/chrono) types.
|
/// GraphQL support for [chrono](https://github.com/chronotope/chrono) types.
|
||||||
pub mod chrono;
|
pub mod chrono;
|
||||||
|
|
||||||
|
#[cfg(feature = "chrono-tz")]
|
||||||
|
/// GraphQL support for [chrono-tz](https://github.com/chronotope/chrono-tz) types.
|
||||||
|
pub mod chrono_tz;
|
||||||
|
|
||||||
#[cfg(feature = "url")]
|
#[cfg(feature = "url")]
|
||||||
/// GraphQL support for [url](https://github.com/servo/rust-url) types.
|
/// GraphQL support for [url](https://github.com/servo/rust-url) types.
|
||||||
pub mod url;
|
pub mod url;
|
||||||
|
|
|
@ -4,8 +4,7 @@ pub mod duplicate;
|
||||||
pub mod parse_impl;
|
pub mod parse_impl;
|
||||||
pub mod span_container;
|
pub mod span_container;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::{collections::HashMap, str::FromStr};
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
use proc_macro2::{Span, TokenStream};
|
use proc_macro2::{Span, TokenStream};
|
||||||
use proc_macro_error::abort;
|
use proc_macro_error::abort;
|
||||||
|
|
Loading…
Reference in a new issue