Use FieldResult for data(), add data_unchecked() for panic

This commit is contained in:
Blaine Bublitz 2020-07-06 16:54:57 -07:00
parent 33f0407dc6
commit c48f126fcd
9 changed files with 29 additions and 20 deletions

View File

@ -11,11 +11,11 @@ struct Query;
#[Object]
impl Query {
async fn borrow_from_context_data<'ctx'>(
async fn borrow_from_context_data<'ctx>(
&self,
ctx: &'ctx Context<'_>
) -> &'ctx String {
ctx.data::<String>
) -> FieldResult<&'ctx String> {
ctx.data::<String>()
}
}
```

View File

@ -28,7 +28,7 @@ impl MyObject {
ctx: &Context<'_>,
#[arg(desc = "Id of object")] id: i64
) -> FieldResult<String> {
let conn = ctx.data::<DbPool>().take();
let conn = ctx.data::<DbPool>()?.take();
Ok(conn.query_something(id)?.name)
}
}

View File

@ -11,11 +11,11 @@ struct Query;
#[Object]
impl Query {
async fn borrow_from_context_data<'ctx'>(
async fn borrow_from_context_data<'ctx>(
&self,
ctx: &'ctx Context<'_>
) -> &'ctx String {
ctx.data::<String>
) -> FieldResult<&'ctx String> {
ctx.data::<String>()
}
}
```
```

View File

@ -26,7 +26,7 @@ impl MyObject {
ctx: &Context<'_>,
#[arg(desc = "Id of object")] id: i64
) -> FieldResult<String> {
let conn = ctx.data::<DbPool>().take();
let conn = ctx.data::<DbPool>()?.take();
Ok(conn.query_something(id)?.name)
}
}

View File

@ -2,7 +2,8 @@ use crate::extensions::Extensions;
use crate::parser::query::{Directive, Field, SelectionSet};
use crate::schema::SchemaEnv;
use crate::{
InputValueType, Lookahead, Pos, Positioned, QueryError, QueryResponse, Result, Type, Value,
FieldResult, InputValueType, Lookahead, Pos, Positioned, QueryError, QueryResponse, Result,
Type, Value,
};
use async_graphql_parser::query::Document;
use async_graphql_parser::UploadValue;
@ -399,12 +400,20 @@ impl<'a, T> ContextBase<'a, T> {
///
/// If both `Schema` and `Query` have the same data type, the data in the `Query` is obtained.
///
/// Returns a FieldError if the specified type data does not exist.
pub fn data<D: Any + Send + Sync>(&self) -> FieldResult<&D> {
self.data_opt::<D>()
.ok_or_else(|| format!("Data `{}` does not exist.", std::any::type_name::<D>()).into())
}
/// Gets the global data defined in the `Context` or `Schema`.
///
/// # Panics
///
/// It will panic if the specified data type does not exist.
pub fn data<D: Any + Send + Sync>(&self) -> &D {
pub fn data_unchecked<D: Any + Send + Sync>(&self) -> &D {
self.data_opt::<D>()
.expect("The specified data type does not exist.")
.unwrap_or_else(|| panic!("Data `{}` does not exist.", std::any::type_name::<D>()))
}
/// Gets the global data defined in the `Context` or `Schema`, returns `None` if the specified type data does not exist.

View File

@ -549,8 +549,8 @@ pub use async_graphql_derive::InputObject;
/// #[Object]
/// impl TypeA {
/// /// Returns data borrowed from the context
/// async fn value_a<'a>(&self, ctx: &'a Context<'_>) -> &'a str {
/// ctx.data::<String>().as_str()
/// async fn value_a<'a>(&self, ctx: &'a Context<'_>) -> FieldResult<&'a str> {
/// Ok(ctx.data::<String>()?.as_str())
/// }
///
/// /// Returns data borrowed self

View File

@ -16,13 +16,13 @@ pub async fn test_mutation_execution_order() {
impl MutationRoot {
async fn append1(&self, ctx: &Context<'_>) -> bool {
async_std::task::sleep(Duration::from_secs(1)).await;
ctx.data::<List>().lock().await.push(1);
ctx.data_unchecked::<List>().lock().await.push(1);
true
}
async fn append2(&self, ctx: &Context<'_>) -> bool {
async_std::task::sleep(Duration::from_millis(500)).await;
ctx.data::<List>().lock().await.push(2);
ctx.data_unchecked::<List>().lock().await.push(2);
true
}
}

View File

@ -157,7 +157,7 @@ pub async fn test_subscription_with_ctx_data() {
#[Object]
impl MyObject {
async fn value(&self, ctx: &Context<'_>) -> i32 {
*ctx.data::<i32>()
*ctx.data_unchecked::<i32>()
}
}
@ -166,7 +166,7 @@ pub async fn test_subscription_with_ctx_data() {
#[Subscription]
impl SubscriptionRoot {
async fn values(&self, ctx: &Context<'_>) -> impl Stream<Item = i32> {
let value = *ctx.data::<i32>();
let value = *ctx.data_unchecked::<i32>();
futures::stream::once(async move { value })
}
@ -217,7 +217,7 @@ pub async fn test_subscription_with_token() {
#[Subscription]
impl SubscriptionRoot {
async fn values(&self, ctx: &Context<'_>) -> FieldResult<impl Stream<Item = i32>> {
if ctx.data::<Token>().0 != "123456" {
if ctx.data_unchecked::<Token>().0 != "123456" {
return Err("forbidden".into());
}
Ok(futures::stream::once(async move { 100 }))

View File

@ -78,7 +78,7 @@ pub async fn test_subscription_ws_transport_with_token() {
#[Subscription]
impl SubscriptionRoot {
async fn values(&self, ctx: &Context<'_>) -> FieldResult<impl Stream<Item = i32>> {
if ctx.data::<Token>().0 != "123456" {
if ctx.data_unchecked::<Token>().0 != "123456" {
return Err("forbidden".into());
}
Ok(futures::stream::iter(0..10))