diff --git a/Cargo.toml b/Cargo.toml index 3a0b0c79..6c9f93ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ dataloader = ["futures-timer", "futures-channel", "lru"] tracing = ["tracinglib", "tracing-futures"] decimal = ["rust_decimal"] cbor = ["serde_cbor"] +chrono-duration = ["chrono", "iso8601-duration"] [dependencies] async-graphql-derive = { path = "derive", version = "=2.11.0" } @@ -50,6 +51,7 @@ mime = "0.3.15" bson = { version = "2.0.0", optional = true, features = ["chrono-0_4"] } chrono = { version = "0.4.19", optional = true } chrono-tz = { version = "0.5.3", optional = true } +iso8601-duration = { version = "0.1.0", optional = true } log = { version = "0.4.14", optional = true } secrecy = { version = "0.7.0", optional = true } tracinglib = { version = "0.1.25", optional = true, package = "tracing" } diff --git a/src/types/external/duration.rs b/src/types/external/duration.rs new file mode 100644 index 00000000..f9b63c76 --- /dev/null +++ b/src/types/external/duration.rs @@ -0,0 +1,21 @@ +use chrono::Duration; +use iso8601_duration as iso8601; + +use crate::{InputValueError, InputValueResult, Scalar, ScalarType, Value}; + +/// Implement the Duration scalar +/// +/// The input/output is a string in ISO8601 format. +#[Scalar(internal, name = "Duration", specified_by_url = "https://en.wikipedia.org/wiki/ISO_8601#Durations")] +impl ScalarType for Duration { + fn parse(value: Value) -> InputValueResult { + match &value { + Value::String(s) => Ok(Duration::from_std(iso8601::Duration::parse(s)?.to_std())?), + _ => Err(InputValueError::expected_type(value)), + } + } + + fn to_value(&self) -> Value { + Value::String(self.to_string()) + } +} diff --git a/src/types/external/mod.rs b/src/types/external/mod.rs index cf109f39..cf3e6b3b 100644 --- a/src/types/external/mod.rs +++ b/src/types/external/mod.rs @@ -18,6 +18,8 @@ mod bson; mod chrono_tz; #[cfg(feature = "chrono")] mod datetime; +#[cfg(feature = "chrono-duration")] +mod duration; #[cfg(feature = "decimal")] mod decimal; #[cfg(feature = "chrono")]