diff --git a/CHANGELOG.md b/CHANGELOG.md index 05f6f8a0..c94c8b79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,10 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] - Add binary types to `ConstValue` and `Value`. [#569](https://github.com/async-graphql/async-graphql/issues/569) +- Implemented `OutputType` for [Bytes](https://docs.rs/bytes/1.0.1/bytes/struct.Bytes.html). - Changed Lookahead to support multiple fields. [#574](https://github.com/async-graphql/async-graphql/issues/574) - Implement `TryFrom<&[SelectionField<'a>]>` for `Lookahead<'a>`. [#575](https://github.com/async-graphql/async-graphql/issues/575) - - Attach custom HTTP headers to the response when an error occurs. [#572](https://github.com/async-graphql/async-graphql/issues/572) +- Allow field visible to support paths. [#578](https://github.com/async-graphql/async-graphql/pull/578) ## [2.9.8] 2021-07-12 diff --git a/Cargo.toml b/Cargo.toml index 9c26acae..850177de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,6 +42,7 @@ static_assertions = "1.1.0" http = "0.2.3" multer = "2.0.0" tempfile = "3.2.0" +bytes = { version = "1.0.1", features = ["serde"] } # Feature optional dependencies bson = { version = "2.0.0-beta.1", optional = true, features = ["chrono-0_4"] } diff --git a/src/types/external/bytes.rs b/src/types/external/bytes.rs new file mode 100644 index 00000000..592c3f30 --- /dev/null +++ b/src/types/external/bytes.rs @@ -0,0 +1,28 @@ +use std::borrow::Cow; + +use bytes::Bytes; + +use crate::parser::types::Field; +use crate::parser::Positioned; +use crate::{registry, ContextSelectionSet, OutputType, ServerResult, Type, Value}; + +impl Type for Bytes { + fn type_name() -> Cow<'static, str> { + Cow::Borrowed("Binary") + } + + fn create_type_info(registry: &mut registry::Registry) -> String { + ::create_type_info(registry) + } +} + +#[async_trait::async_trait] +impl OutputType for Bytes { + async fn resolve( + &self, + _: &ContextSelectionSet<'_>, + _field: &Positioned, + ) -> ServerResult { + Ok(Value::Binary(self.clone())) + } +} diff --git a/src/types/external/mod.rs b/src/types/external/mod.rs index 02e98bd0..cf109f39 100644 --- a/src/types/external/mod.rs +++ b/src/types/external/mod.rs @@ -1,6 +1,7 @@ //! Implementations of `Type`, `ScalarType`, etc on external types. mod bool; +mod bytes; mod char; mod cow; mod floats; diff --git a/tests/binary.rs b/tests/binary.rs new file mode 100644 index 00000000..2f46d78f --- /dev/null +++ b/tests/binary.rs @@ -0,0 +1,22 @@ +use async_graphql::*; +use bytes::Bytes; + +#[tokio::test] +pub async fn test_batch_request() { + struct Query; + + #[Object] + impl Query { + async fn data(&self) -> Bytes { + Bytes::from_static(b"abcdef") + } + } + + let schema = Schema::new(Query, EmptyMutation, EmptySubscription); + assert_eq!( + schema.execute("{ data }").await.into_result().unwrap().data, + value!({ + "data": Bytes::from_static(b"abcdef"), + }) + ); +} diff --git a/value/Cargo.toml b/value/Cargo.toml index 4bd3289d..c07fab57 100644 --- a/value/Cargo.toml +++ b/value/Cargo.toml @@ -14,3 +14,4 @@ categories = ["network-programming", "asynchronous"] [dependencies] serde_json = "1.0.64" serde = { version = "1.0.125", features = ["derive"] } +bytes = { version = "1.0.1", features = ["serde"] } diff --git a/value/src/deserializer.rs b/value/src/deserializer.rs index 0113b72b..e473cae1 100644 --- a/value/src/deserializer.rs +++ b/value/src/deserializer.rs @@ -113,7 +113,7 @@ impl<'de> de::Deserializer<'de> for ConstValue { .map_err(|err| DeserializerError(err.to_string())), ConstValue::String(v) => visitor.visit_str(&v), ConstValue::Boolean(v) => visitor.visit_bool(v), - ConstValue::Binary(bytes) => visitor.visit_byte_buf(bytes), + ConstValue::Binary(bytes) => visitor.visit_bytes(&*bytes), ConstValue::Enum(v) => visitor.visit_str(v.as_str()), ConstValue::List(v) => visit_array(v, visitor), ConstValue::Object(v) => visit_object(v, visitor), diff --git a/value/src/lib.rs b/value/src/lib.rs index 9c094149..fd44e9e6 100644 --- a/value/src/lib.rs +++ b/value/src/lib.rs @@ -17,6 +17,7 @@ use std::iter::FromIterator; use std::ops::Deref; use std::sync::Arc; +use bytes::Bytes; use serde::{Deserialize, Deserializer, Serialize, Serializer}; pub use deserializer::{from_value, DeserializerError}; @@ -132,7 +133,7 @@ pub enum ConstValue { /// A boolean. Boolean(bool), /// A binary. - Binary(Vec), + Binary(Bytes), /// An enum. These are typically in `SCREAMING_SNAKE_CASE`. Enum(Name), /// A list of values. @@ -357,7 +358,7 @@ pub enum Value { /// A boolean. Boolean(bool), /// A binary. - Binary(Vec), + Binary(Bytes), /// An enum. These are typically in `SCREAMING_SNAKE_CASE`. Enum(Name), /// A list of values. diff --git a/value/src/serializer.rs b/value/src/serializer.rs index 57e3706e..90fabc9b 100644 --- a/value/src/serializer.rs +++ b/value/src/serializer.rs @@ -120,7 +120,7 @@ impl ser::Serializer for Serializer { #[inline] fn serialize_bytes(self, v: &[u8]) -> Result { - Ok(ConstValue::Binary(v.to_vec())) + Ok(ConstValue::Binary(v.to_vec().into())) } #[inline] diff --git a/value/src/value_serde.rs b/value/src/value_serde.rs index 6011e204..7e2ffb7a 100644 --- a/value/src/value_serde.rs +++ b/value/src/value_serde.rs @@ -87,7 +87,7 @@ impl<'de> Deserialize<'de> for ConstValue { where E: DeError, { - Ok(ConstValue::Binary(v.to_vec())) + Ok(ConstValue::Binary(v.to_vec().into())) } #[inline] @@ -95,7 +95,7 @@ impl<'de> Deserialize<'de> for ConstValue { where E: DeError, { - Ok(ConstValue::Binary(v)) + Ok(ConstValue::Binary(v.into())) } #[inline] @@ -230,7 +230,7 @@ impl<'de> Deserialize<'de> for Value { where E: DeError, { - Ok(Value::Binary(v.to_vec())) + Ok(Value::Binary(v.to_vec().into())) } #[inline] @@ -238,7 +238,7 @@ impl<'de> Deserialize<'de> for Value { where E: DeError, { - Ok(Value::Binary(v)) + Ok(Value::Binary(v.into())) } #[inline] diff --git a/value/tests/test_serde.rs b/value/tests/test_serde.rs index 916a0e80..2877d5a5 100644 --- a/value/tests/test_serde.rs +++ b/value/tests/test_serde.rs @@ -1,4 +1,5 @@ use async_graphql_value::*; +use bytes::Bytes; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; @@ -57,7 +58,12 @@ fn test_serde() { #[test] fn test_binary() { assert_eq!( - to_value(Value::Binary(b"123456".to_vec())).unwrap(), - ConstValue::Binary(b"123456".to_vec()) + to_value(Bytes::from_static(b"123456")).unwrap(), + ConstValue::Binary(Bytes::from_static(b"123456")) + ); + + assert_eq!( + from_value::(ConstValue::Binary(Bytes::from_static(b"123456"))).unwrap(), + Bytes::from_static(b"123456") ); }