async_graphql/types/external/
cow.rs1use std::borrow::Cow;
2
3use async_graphql_parser::types::Field;
4
5use crate::{registry, ContextSelectionSet, OutputType, Positioned, ServerResult, Value};
6
7#[cfg_attr(feature = "boxed-trait", async_trait::async_trait)]
8impl<T> OutputType for Cow<'_, T>
9where
10 T: OutputType + ToOwned + ?Sized,
11 <T as ToOwned>::Owned: Send + Sync,
12{
13 fn type_name() -> Cow<'static, str> {
14 T::type_name()
15 }
16
17 fn create_type_info(registry: &mut registry::Registry) -> String {
18 <T as OutputType>::create_type_info(registry)
19 }
20
21 async fn resolve(
22 &self,
23 ctx: &ContextSelectionSet<'_>,
24 field: &Positioned<Field>,
25 ) -> ServerResult<Value> {
26 self.as_ref().resolve(ctx, field).await
27 }
28}
29
30#[cfg(test)]
31mod test {
32 use std::borrow::Cow;
33
34 use crate::*;
35
36 #[tokio::test]
37 async fn test_cow_type() {
38 struct Query {
39 obj: MyObj,
40 }
41
42 #[derive(SimpleObject, Clone)]
43 #[graphql(internal)]
44 struct MyObj {
45 a: i32,
46 b: i32,
47 }
48
49 #[Object(internal)]
50 impl Query {
51 async fn value1(&self) -> Cow<'_, str> {
52 Cow::Borrowed("abc")
53 }
54
55 async fn value2(&self) -> Cow<'_, str> {
56 Cow::Owned("def".to_string())
57 }
58
59 async fn obj1(&self) -> Cow<'_, MyObj> {
60 Cow::Borrowed(&self.obj)
61 }
62
63 async fn obj2(&self) -> Cow<'_, MyObj> {
64 Cow::Owned(MyObj { a: 300, b: 400 })
65 }
66 }
67
68 let query = r#"{
69 value1
70 value2
71 obj1 {
72 a b
73 }
74 obj2 {
75 a b
76 }
77 }"#;
78 let schema = Schema::new(
79 Query {
80 obj: MyObj { a: 100, b: 200 },
81 },
82 EmptyMutation,
83 EmptySubscription,
84 );
85
86 assert_eq!(
87 schema.execute(query).await.into_result().unwrap().data,
88 value!({
89 "value1": "abc",
90 "value2": "def",
91 "obj1": {"a": 100, "b": 200},
92 "obj2": {"a": 300, "b": 400},
93 })
94 );
95 }
96}