Implemented `OutputType` for Bytes. #569
This commit is contained in:
parent
863380ee1f
commit
ecf8890e7e
|
@ -7,10 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
- Add binary types to `ConstValue` and `Value`. [#569](https://github.com/async-graphql/async-graphql/issues/569)
|
- 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)
|
- 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)
|
- 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)
|
- 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
|
## [2.9.8] 2021-07-12
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ static_assertions = "1.1.0"
|
||||||
http = "0.2.3"
|
http = "0.2.3"
|
||||||
multer = "2.0.0"
|
multer = "2.0.0"
|
||||||
tempfile = "3.2.0"
|
tempfile = "3.2.0"
|
||||||
|
bytes = { version = "1.0.1", features = ["serde"] }
|
||||||
|
|
||||||
# Feature optional dependencies
|
# Feature optional dependencies
|
||||||
bson = { version = "2.0.0-beta.1", optional = true, features = ["chrono-0_4"] }
|
bson = { version = "2.0.0-beta.1", optional = true, features = ["chrono-0_4"] }
|
||||||
|
|
|
@ -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()))
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
//! Implementations of `Type`, `ScalarType`, etc on external types.
|
//! Implementations of `Type`, `ScalarType`, etc on external types.
|
||||||
|
|
||||||
mod bool;
|
mod bool;
|
||||||
|
mod bytes;
|
||||||
mod char;
|
mod char;
|
||||||
mod cow;
|
mod cow;
|
||||||
mod floats;
|
mod floats;
|
||||||
|
|
|
@ -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"),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
|
@ -14,3 +14,4 @@ categories = ["network-programming", "asynchronous"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde_json = "1.0.64"
|
serde_json = "1.0.64"
|
||||||
serde = { version = "1.0.125", features = ["derive"] }
|
serde = { version = "1.0.125", features = ["derive"] }
|
||||||
|
bytes = { version = "1.0.1", features = ["serde"] }
|
||||||
|
|
|
@ -113,7 +113,7 @@ impl<'de> de::Deserializer<'de> for ConstValue {
|
||||||
.map_err(|err| DeserializerError(err.to_string())),
|
.map_err(|err| DeserializerError(err.to_string())),
|
||||||
ConstValue::String(v) => visitor.visit_str(&v),
|
ConstValue::String(v) => visitor.visit_str(&v),
|
||||||
ConstValue::Boolean(v) => visitor.visit_bool(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::Enum(v) => visitor.visit_str(v.as_str()),
|
||||||
ConstValue::List(v) => visit_array(v, visitor),
|
ConstValue::List(v) => visit_array(v, visitor),
|
||||||
ConstValue::Object(v) => visit_object(v, visitor),
|
ConstValue::Object(v) => visit_object(v, visitor),
|
||||||
|
|
|
@ -17,6 +17,7 @@ use std::iter::FromIterator;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use bytes::Bytes;
|
||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
|
||||||
pub use deserializer::{from_value, DeserializerError};
|
pub use deserializer::{from_value, DeserializerError};
|
||||||
|
@ -132,7 +133,7 @@ pub enum ConstValue {
|
||||||
/// A boolean.
|
/// A boolean.
|
||||||
Boolean(bool),
|
Boolean(bool),
|
||||||
/// A binary.
|
/// A binary.
|
||||||
Binary(Vec<u8>),
|
Binary(Bytes),
|
||||||
/// An enum. These are typically in `SCREAMING_SNAKE_CASE`.
|
/// An enum. These are typically in `SCREAMING_SNAKE_CASE`.
|
||||||
Enum(Name),
|
Enum(Name),
|
||||||
/// A list of values.
|
/// A list of values.
|
||||||
|
@ -357,7 +358,7 @@ pub enum Value {
|
||||||
/// A boolean.
|
/// A boolean.
|
||||||
Boolean(bool),
|
Boolean(bool),
|
||||||
/// A binary.
|
/// A binary.
|
||||||
Binary(Vec<u8>),
|
Binary(Bytes),
|
||||||
/// An enum. These are typically in `SCREAMING_SNAKE_CASE`.
|
/// An enum. These are typically in `SCREAMING_SNAKE_CASE`.
|
||||||
Enum(Name),
|
Enum(Name),
|
||||||
/// A list of values.
|
/// A list of values.
|
||||||
|
|
|
@ -120,7 +120,7 @@ impl ser::Serializer for Serializer {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
|
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]
|
#[inline]
|
||||||
|
|
|
@ -87,7 +87,7 @@ impl<'de> Deserialize<'de> for ConstValue {
|
||||||
where
|
where
|
||||||
E: DeError,
|
E: DeError,
|
||||||
{
|
{
|
||||||
Ok(ConstValue::Binary(v.to_vec()))
|
Ok(ConstValue::Binary(v.to_vec().into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -95,7 +95,7 @@ impl<'de> Deserialize<'de> for ConstValue {
|
||||||
where
|
where
|
||||||
E: DeError,
|
E: DeError,
|
||||||
{
|
{
|
||||||
Ok(ConstValue::Binary(v))
|
Ok(ConstValue::Binary(v.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -230,7 +230,7 @@ impl<'de> Deserialize<'de> for Value {
|
||||||
where
|
where
|
||||||
E: DeError,
|
E: DeError,
|
||||||
{
|
{
|
||||||
Ok(Value::Binary(v.to_vec()))
|
Ok(Value::Binary(v.to_vec().into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -238,7 +238,7 @@ impl<'de> Deserialize<'de> for Value {
|
||||||
where
|
where
|
||||||
E: DeError,
|
E: DeError,
|
||||||
{
|
{
|
||||||
Ok(Value::Binary(v))
|
Ok(Value::Binary(v.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use async_graphql_value::*;
|
use async_graphql_value::*;
|
||||||
|
use bytes::Bytes;
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
@ -57,7 +58,12 @@ fn test_serde() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_binary() {
|
fn test_binary() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
to_value(Value::Binary(b"123456".to_vec())).unwrap(),
|
to_value(Bytes::from_static(b"123456")).unwrap(),
|
||||||
ConstValue::Binary(b"123456".to_vec())
|
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")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue