Implemented `OutputType` for Bytes. #569

This commit is contained in:
Sunli 2021-07-18 21:42:39 +08:00
parent 863380ee1f
commit ecf8890e7e
11 changed files with 72 additions and 11 deletions

View File

@ -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

View File

@ -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"] }

28
src/types/external/bytes.rs vendored Normal file
View File

@ -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 {
<String as Type>::create_type_info(registry)
}
}
#[async_trait::async_trait]
impl OutputType for Bytes {
async fn resolve(
&self,
_: &ContextSelectionSet<'_>,
_field: &Positioned<Field>,
) -> ServerResult<Value> {
Ok(Value::Binary(self.clone()))
}
}

View File

@ -1,6 +1,7 @@
//! Implementations of `Type`, `ScalarType`, etc on external types.
mod bool;
mod bytes;
mod char;
mod cow;
mod floats;

22
tests/binary.rs Normal file
View File

@ -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"),
})
);
}

View File

@ -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"] }

View File

@ -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),

View File

@ -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<u8>),
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<u8>),
Binary(Bytes),
/// An enum. These are typically in `SCREAMING_SNAKE_CASE`.
Enum(Name),
/// A list of values.

View File

@ -120,7 +120,7 @@ impl ser::Serializer for Serializer {
#[inline]
fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
Ok(ConstValue::Binary(v.to_vec()))
Ok(ConstValue::Binary(v.to_vec().into()))
}
#[inline]

View File

@ -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]

View File

@ -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::<Bytes>(ConstValue::Binary(Bytes::from_static(b"123456"))).unwrap(),
Bytes::from_static(b"123456")
);
}