mirror of
https://github.com/actix/examples
synced 2024-11-23 14:31:07 +01:00
update async-graphql deps
This commit is contained in:
parent
a46a459476
commit
0a201cd860
80
Cargo.lock
generated
80
Cargo.lock
generated
@ -794,9 +794,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "async-graphql"
|
||||
version = "3.0.38"
|
||||
version = "4.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2106123e9c79a8d649bf0f7e9f58462a90ce2ca71ad9a0b69b4f2b67382c376f"
|
||||
checksum = "ffffea596a12b6d9ea5c6fc8a5f414cf4e0c8cd6b618ac2c3d4f56d9b5c5520b"
|
||||
dependencies = [
|
||||
"async-graphql-derive",
|
||||
"async-graphql-parser",
|
||||
@ -824,9 +824,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "async-graphql-actix-web"
|
||||
version = "3.0.38"
|
||||
version = "4.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "444088fb3f4faeaf1e235df5e485c0595a4ec3d9f73bcba3ceee4ba6a97a9fdf"
|
||||
checksum = "efa4e7d1a4bc86b2f9bad704aefb1493c2eb6edb52706dad3f9551c148e4c284"
|
||||
dependencies = [
|
||||
"actix 0.13.0",
|
||||
"actix-http",
|
||||
@ -845,7 +845,7 @@ dependencies = [
|
||||
name = "async-graphql-demo"
|
||||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"actix 0.12.0",
|
||||
"actix 0.13.0",
|
||||
"actix-cors",
|
||||
"actix-web",
|
||||
"actix-web-lab",
|
||||
@ -858,13 +858,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "async-graphql-derive"
|
||||
version = "3.0.38"
|
||||
version = "4.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a6ec150ac445a660169a3ad5075b953a7351ec75fe28095e639f6282aac9fdb"
|
||||
checksum = "7082221cc1dc29edec0e3225420146b1fbc7f18ba534e301eab186501ae84c28"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"async-graphql-parser",
|
||||
"darling",
|
||||
"darling 0.14.1",
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -874,22 +874,21 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "async-graphql-parser"
|
||||
version = "3.0.38"
|
||||
version = "4.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0302764f05e0e50fd3b381646d4a0ed07d4ce5c9fc1eaf79bbd7745bd4893adb"
|
||||
checksum = "c328e2cb0dade64333859f7a7e22c9e19a3767afaad673976a1d855c9bda5ffa"
|
||||
dependencies = [
|
||||
"async-graphql-value",
|
||||
"pest",
|
||||
"pest_derive",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-graphql-value"
|
||||
version = "3.0.38"
|
||||
version = "4.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba2e19876bcd2068f597fd0182f4ba602ce3c89cb04c4b8810d7c36f44724e92"
|
||||
checksum = "005292494ce718604a0dc1531e5827fe540761e1df44b064085711c5fde70b7c"
|
||||
dependencies = [
|
||||
"bytes 1.1.0",
|
||||
"indexmap",
|
||||
@ -1770,8 +1769,18 @@ version = "0.13.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"darling_macro",
|
||||
"darling_core 0.13.4",
|
||||
"darling_macro 0.13.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4529658bdda7fd6769b8614be250cdcfc3aeb0ee72fe66f9e41e5e5eb73eac02"
|
||||
dependencies = [
|
||||
"darling_core 0.14.1",
|
||||
"darling_macro 0.14.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1788,13 +1797,38 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_core"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "649c91bc01e8b1eac09fb91e8dbc7d517684ca6be8ebc75bb9cafc894f9fdb6f"
|
||||
dependencies = [
|
||||
"fnv",
|
||||
"ident_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim 0.10.0",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_macro"
|
||||
version = "0.13.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"darling_core 0.13.4",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_macro"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddfc69c5bfcbd2fc09a0f38451d2daf0e372e367986a83906d1b0dbc88134fb5"
|
||||
dependencies = [
|
||||
"darling_core 0.14.1",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
@ -4214,11 +4248,11 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.36"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
|
||||
checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5137,7 +5171,7 @@ version = "1.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"darling 0.13.4",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
@ -6336,6 +6370,12 @@ version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.21"
|
||||
|
@ -5,6 +5,6 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
actix-web = "4"
|
||||
casbin = "2.0.9"
|
||||
casbin = "2"
|
||||
loge = { version = "0.4", default-features = false, features = ["colored", "chrono"] }
|
||||
tokio = { version = "1.16.1", features = ["sync"] }
|
||||
tokio = { version = "1.13.1", features = ["sync"] }
|
||||
|
@ -4,14 +4,14 @@ version = "1.0.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
actix = "0.12"
|
||||
actix = "0.13"
|
||||
actix-web = "4"
|
||||
actix-web-lab = "0.16"
|
||||
actix-cors = "0.6"
|
||||
|
||||
async-graphql = "3"
|
||||
async-graphql-actix-web = "3"
|
||||
async-graphql = "4"
|
||||
async-graphql-actix-web = "4"
|
||||
|
||||
env_logger = "0.9"
|
||||
log = "0.4"
|
||||
slab = "0.4.2"
|
||||
slab = "0.4"
|
||||
|
@ -1,17 +1,18 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use async_graphql::{EmptyMutation, EmptySubscription, Schema};
|
||||
use model::Episode;
|
||||
use slab::Slab;
|
||||
|
||||
pub type StarWarsSchema = Schema<QueryRoot, EmptyMutation, EmptySubscription>;
|
||||
|
||||
mod model;
|
||||
pub use self::model::QueryRoot;
|
||||
use model::Episode;
|
||||
pub use model::QueryRoot;
|
||||
|
||||
pub type StarWarsSchema = Schema<QueryRoot, EmptyMutation, EmptySubscription>;
|
||||
|
||||
pub struct StarWarsChar {
|
||||
id: &'static str,
|
||||
name: &'static str,
|
||||
is_human: bool,
|
||||
friends: Vec<usize>,
|
||||
appears_in: Vec<Episode>,
|
||||
home_planet: Option<&'static str>,
|
||||
@ -22,8 +23,7 @@ pub struct StarWars {
|
||||
luke: usize,
|
||||
artoo: usize,
|
||||
chars: Slab<StarWarsChar>,
|
||||
human_data: HashMap<&'static str, usize>,
|
||||
droid_data: HashMap<&'static str, usize>,
|
||||
chars_by_id: HashMap<&'static str, usize>,
|
||||
}
|
||||
|
||||
impl StarWars {
|
||||
@ -34,6 +34,7 @@ impl StarWars {
|
||||
let luke = chars.insert(StarWarsChar {
|
||||
id: "1000",
|
||||
name: "Luke Skywalker",
|
||||
is_human: true,
|
||||
friends: vec![],
|
||||
appears_in: vec![],
|
||||
home_planet: Some("Tatooine"),
|
||||
@ -42,7 +43,8 @@ impl StarWars {
|
||||
|
||||
let vader = chars.insert(StarWarsChar {
|
||||
id: "1001",
|
||||
name: "Luke Skywalker",
|
||||
name: "Anakin Skywalker",
|
||||
is_human: true,
|
||||
friends: vec![],
|
||||
appears_in: vec![],
|
||||
home_planet: Some("Tatooine"),
|
||||
@ -52,6 +54,7 @@ impl StarWars {
|
||||
let han = chars.insert(StarWarsChar {
|
||||
id: "1002",
|
||||
name: "Han Solo",
|
||||
is_human: true,
|
||||
friends: vec![],
|
||||
appears_in: vec![Episode::Empire, Episode::NewHope, Episode::Jedi],
|
||||
home_planet: None,
|
||||
@ -61,6 +64,7 @@ impl StarWars {
|
||||
let leia = chars.insert(StarWarsChar {
|
||||
id: "1003",
|
||||
name: "Leia Organa",
|
||||
is_human: true,
|
||||
friends: vec![],
|
||||
appears_in: vec![Episode::Empire, Episode::NewHope, Episode::Jedi],
|
||||
home_planet: Some("Alderaa"),
|
||||
@ -70,6 +74,7 @@ impl StarWars {
|
||||
let tarkin = chars.insert(StarWarsChar {
|
||||
id: "1004",
|
||||
name: "Wilhuff Tarkin",
|
||||
is_human: true,
|
||||
friends: vec![],
|
||||
appears_in: vec![Episode::Empire, Episode::NewHope, Episode::Jedi],
|
||||
home_planet: None,
|
||||
@ -79,6 +84,7 @@ impl StarWars {
|
||||
let threepio = chars.insert(StarWarsChar {
|
||||
id: "2000",
|
||||
name: "C-3PO",
|
||||
is_human: false,
|
||||
friends: vec![],
|
||||
appears_in: vec![Episode::Empire, Episode::NewHope, Episode::Jedi],
|
||||
home_planet: None,
|
||||
@ -88,6 +94,7 @@ impl StarWars {
|
||||
let artoo = chars.insert(StarWarsChar {
|
||||
id: "2001",
|
||||
name: "R2-D2",
|
||||
is_human: false,
|
||||
friends: vec![],
|
||||
appears_in: vec![Episode::Empire, Episode::NewHope, Episode::Jedi],
|
||||
home_planet: None,
|
||||
@ -102,39 +109,52 @@ impl StarWars {
|
||||
chars[threepio].friends = vec![luke, han, leia, artoo];
|
||||
chars[artoo].friends = vec![luke, han, leia];
|
||||
|
||||
let mut human_data = HashMap::new();
|
||||
human_data.insert("1000", luke);
|
||||
human_data.insert("1001", vader);
|
||||
human_data.insert("1002", han);
|
||||
human_data.insert("1003", leia);
|
||||
human_data.insert("1004", tarkin);
|
||||
|
||||
let mut droid_data = HashMap::new();
|
||||
droid_data.insert("2000", threepio);
|
||||
droid_data.insert("2001", artoo);
|
||||
|
||||
let chars_by_id = chars.iter().map(|(idx, ch)| (ch.id, idx)).collect();
|
||||
Self {
|
||||
luke,
|
||||
artoo,
|
||||
chars,
|
||||
human_data,
|
||||
droid_data,
|
||||
chars_by_id,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn human(&self, id: &str) -> Option<usize> {
|
||||
self.human_data.get(id).cloned()
|
||||
pub fn human(&self, id: &str) -> Option<&StarWarsChar> {
|
||||
self.chars_by_id
|
||||
.get(id)
|
||||
.copied()
|
||||
.map(|idx| self.chars.get(idx).unwrap())
|
||||
.filter(|ch| ch.is_human)
|
||||
}
|
||||
|
||||
pub fn droid(&self, id: &str) -> Option<usize> {
|
||||
self.droid_data.get(id).cloned()
|
||||
pub fn droid(&self, id: &str) -> Option<&StarWarsChar> {
|
||||
self.chars_by_id
|
||||
.get(id)
|
||||
.copied()
|
||||
.map(|idx| self.chars.get(idx).unwrap())
|
||||
.filter(|ch| !ch.is_human)
|
||||
}
|
||||
|
||||
pub fn humans(&self) -> Vec<usize> {
|
||||
self.human_data.values().cloned().collect()
|
||||
pub fn humans(&self) -> Vec<&StarWarsChar> {
|
||||
self.chars
|
||||
.iter()
|
||||
.filter(|(_, ch)| ch.is_human)
|
||||
.map(|(_, ch)| ch)
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn droids(&self) -> Vec<usize> {
|
||||
self.droid_data.values().cloned().collect()
|
||||
pub fn droids(&self) -> Vec<&StarWarsChar> {
|
||||
self.chars
|
||||
.iter()
|
||||
.filter(|(_, ch)| !ch.is_human)
|
||||
.map(|(_, ch)| ch)
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn friends(&self, ch: &StarWarsChar) -> Vec<&StarWarsChar> {
|
||||
ch.friends
|
||||
.iter()
|
||||
.copied()
|
||||
.filter_map(|id| self.chars.get(id))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
use async_graphql::connection::{query, Connection, Edge, EmptyFields};
|
||||
use async_graphql::{Context, Enum, FieldResult, Interface, Object};
|
||||
use async_graphql::{
|
||||
connection::{query, Connection, Edge},
|
||||
Context, Enum, Error, Interface, Object, OutputType, Result,
|
||||
};
|
||||
|
||||
use super::StarWars;
|
||||
use super::{StarWars, StarWarsChar};
|
||||
|
||||
/// One of the films in the Star Wars Trilogy
|
||||
#[derive(Enum, Copy, Clone, Eq, PartialEq)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Enum)]
|
||||
pub enum Episode {
|
||||
/// Released in 1977.
|
||||
NewHope,
|
||||
@ -16,73 +18,85 @@ pub enum Episode {
|
||||
Jedi,
|
||||
}
|
||||
|
||||
pub struct Human(usize);
|
||||
pub struct Human<'a>(&'a StarWarsChar);
|
||||
|
||||
/// A humanoid creature in the Star Wars universe.
|
||||
#[Object]
|
||||
impl Human {
|
||||
impl<'a> Human<'a> {
|
||||
/// The id of the human.
|
||||
async fn id(&self, ctx: &Context<'_>) -> &str {
|
||||
ctx.data_unchecked::<StarWars>().chars[self.0].id
|
||||
async fn id(&self) -> &str {
|
||||
self.0.id
|
||||
}
|
||||
|
||||
/// The name of the human.
|
||||
async fn name(&self, ctx: &Context<'_>) -> &str {
|
||||
ctx.data_unchecked::<StarWars>().chars[self.0].name
|
||||
async fn name(&self) -> &str {
|
||||
self.0.name
|
||||
}
|
||||
|
||||
/// The friends of the human, or an empty list if they have none.
|
||||
async fn friends(&self, ctx: &Context<'_>) -> Vec<Character> {
|
||||
ctx.data_unchecked::<StarWars>().chars[self.0]
|
||||
.friends
|
||||
.iter()
|
||||
.map(|id| Human(*id).into())
|
||||
async fn friends<'ctx>(&self, ctx: &Context<'ctx>) -> Vec<Character<'ctx>> {
|
||||
ctx.data_unchecked::<StarWars>()
|
||||
.friends(self.0)
|
||||
.into_iter()
|
||||
.map(|ch| {
|
||||
if ch.is_human {
|
||||
Human(ch).into()
|
||||
} else {
|
||||
Droid(ch).into()
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Which movies they appear in.
|
||||
async fn appears_in<'a>(&self, ctx: &'a Context<'_>) -> &'a [Episode] {
|
||||
&ctx.data_unchecked::<StarWars>().chars[self.0].appears_in
|
||||
async fn appears_in(&self) -> &[Episode] {
|
||||
&self.0.appears_in
|
||||
}
|
||||
|
||||
/// The home planet of the human, or null if unknown.
|
||||
async fn home_planet<'a>(&self, ctx: &'a Context<'_>) -> &'a Option<&'a str> {
|
||||
&ctx.data_unchecked::<StarWars>().chars[self.0].home_planet
|
||||
async fn home_planet(&self) -> &Option<&str> {
|
||||
&self.0.home_planet
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Droid(usize);
|
||||
pub struct Droid<'a>(&'a StarWarsChar);
|
||||
|
||||
/// A mechanical creature in the Star Wars universe.
|
||||
#[Object]
|
||||
impl Droid {
|
||||
impl<'a> Droid<'a> {
|
||||
/// The id of the droid.
|
||||
async fn id(&self, ctx: &Context<'_>) -> &str {
|
||||
ctx.data_unchecked::<StarWars>().chars[self.0].id
|
||||
async fn id(&self) -> &str {
|
||||
self.0.id
|
||||
}
|
||||
|
||||
/// The name of the droid.
|
||||
async fn name(&self, ctx: &Context<'_>) -> &str {
|
||||
ctx.data_unchecked::<StarWars>().chars[self.0].name
|
||||
async fn name(&self) -> &str {
|
||||
self.0.name
|
||||
}
|
||||
|
||||
/// The friends of the droid, or an empty list if they have none.
|
||||
async fn friends(&self, ctx: &Context<'_>) -> Vec<Character> {
|
||||
ctx.data_unchecked::<StarWars>().chars[self.0]
|
||||
.friends
|
||||
.iter()
|
||||
.map(|id| Droid(*id).into())
|
||||
async fn friends<'ctx>(&self, ctx: &Context<'ctx>) -> Vec<Character<'ctx>> {
|
||||
ctx.data_unchecked::<StarWars>()
|
||||
.friends(self.0)
|
||||
.into_iter()
|
||||
.map(|ch| {
|
||||
if ch.is_human {
|
||||
Human(ch).into()
|
||||
} else {
|
||||
Droid(ch).into()
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Which movies they appear in.
|
||||
async fn appears_in<'a>(&self, ctx: &'a Context<'_>) -> &'a [Episode] {
|
||||
&ctx.data_unchecked::<StarWars>().chars[self.0].appears_in
|
||||
async fn appears_in(&self) -> &[Episode] {
|
||||
&self.0.appears_in
|
||||
}
|
||||
|
||||
/// The primary function of the droid.
|
||||
async fn primary_function<'a>(&self, ctx: &'a Context<'_>) -> &'a Option<&'a str> {
|
||||
&ctx.data_unchecked::<StarWars>().chars[self.0].primary_function
|
||||
async fn primary_function(&self) -> &Option<&str> {
|
||||
&self.0.primary_function
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,65 +104,67 @@ pub struct QueryRoot;
|
||||
|
||||
#[Object]
|
||||
impl QueryRoot {
|
||||
async fn hero(
|
||||
async fn hero<'a>(
|
||||
&self,
|
||||
ctx: &Context<'_>,
|
||||
ctx: &Context<'a>,
|
||||
#[graphql(
|
||||
desc = "If omitted, returns the hero of the whole saga. If provided, returns the hero of that particular episode."
|
||||
)]
|
||||
episode: Episode,
|
||||
) -> Character {
|
||||
if episode == Episode::Empire {
|
||||
Human(ctx.data_unchecked::<StarWars>().luke).into()
|
||||
episode: Option<Episode>,
|
||||
) -> Character<'a> {
|
||||
let star_wars = ctx.data_unchecked::<StarWars>();
|
||||
|
||||
match episode {
|
||||
Some(episode_name) => {
|
||||
if episode_name == Episode::Empire {
|
||||
Human(star_wars.chars.get(star_wars.luke).unwrap()).into()
|
||||
} else {
|
||||
Droid(ctx.data_unchecked::<StarWars>().artoo).into()
|
||||
Droid(star_wars.chars.get(star_wars.artoo).unwrap()).into()
|
||||
}
|
||||
}
|
||||
|
||||
async fn human(
|
||||
None => Human(star_wars.chars.get(star_wars.luke).unwrap()).into(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn human<'a>(
|
||||
&self,
|
||||
ctx: &Context<'_>,
|
||||
ctx: &Context<'a>,
|
||||
#[graphql(desc = "id of the human")] id: String,
|
||||
) -> Option<Human> {
|
||||
) -> Option<Human<'a>> {
|
||||
ctx.data_unchecked::<StarWars>().human(&id).map(Human)
|
||||
}
|
||||
|
||||
async fn humans(
|
||||
async fn humans<'a>(
|
||||
&self,
|
||||
ctx: &Context<'_>,
|
||||
ctx: &Context<'a>,
|
||||
after: Option<String>,
|
||||
before: Option<String>,
|
||||
first: Option<i32>,
|
||||
last: Option<i32>,
|
||||
) -> FieldResult<Connection<usize, Human, EmptyFields, EmptyFields>> {
|
||||
) -> Result<Connection<usize, Human<'a>>> {
|
||||
let humans = ctx.data_unchecked::<StarWars>().humans().to_vec();
|
||||
|
||||
query_characters(after, before, first, last, &humans)
|
||||
.await
|
||||
.map(|conn| conn.map_node(Human))
|
||||
query_characters(after, before, first, last, &humans, Human).await
|
||||
}
|
||||
|
||||
async fn droid(
|
||||
async fn droid<'a>(
|
||||
&self,
|
||||
ctx: &Context<'_>,
|
||||
ctx: &Context<'a>,
|
||||
#[graphql(desc = "id of the droid")] id: String,
|
||||
) -> Option<Droid> {
|
||||
) -> Option<Droid<'a>> {
|
||||
ctx.data_unchecked::<StarWars>().droid(&id).map(Droid)
|
||||
}
|
||||
|
||||
async fn droids(
|
||||
async fn droids<'a>(
|
||||
&self,
|
||||
ctx: &Context<'_>,
|
||||
ctx: &Context<'a>,
|
||||
after: Option<String>,
|
||||
before: Option<String>,
|
||||
first: Option<i32>,
|
||||
last: Option<i32>,
|
||||
) -> FieldResult<Connection<usize, Droid, EmptyFields, EmptyFields>> {
|
||||
) -> Result<Connection<usize, Droid<'a>>> {
|
||||
let droids = ctx.data_unchecked::<StarWars>().droids().to_vec();
|
||||
|
||||
query_characters(after, before, first, last, &droids)
|
||||
.await
|
||||
.map(|conn| conn.map_node(Droid))
|
||||
query_characters(after, before, first, last, &droids, Droid).await
|
||||
}
|
||||
}
|
||||
|
||||
@ -156,21 +172,26 @@ impl QueryRoot {
|
||||
#[graphql(
|
||||
field(name = "id", type = "&str"),
|
||||
field(name = "name", type = "&str"),
|
||||
field(name = "friends", type = "Vec<Character>"),
|
||||
field(name = "appears_in", type = "&'ctx [Episode]")
|
||||
field(name = "friends", type = "Vec<Character<'ctx>>"),
|
||||
field(name = "appears_in", type = "&[Episode]")
|
||||
)]
|
||||
pub enum Character {
|
||||
Human(Human),
|
||||
Droid(Droid),
|
||||
pub enum Character<'a> {
|
||||
Human(Human<'a>),
|
||||
Droid(Droid<'a>),
|
||||
}
|
||||
|
||||
async fn query_characters(
|
||||
async fn query_characters<'a, F, T>(
|
||||
after: Option<String>,
|
||||
before: Option<String>,
|
||||
first: Option<i32>,
|
||||
last: Option<i32>,
|
||||
characters: &[usize],
|
||||
) -> FieldResult<Connection<usize, usize, EmptyFields, EmptyFields>> {
|
||||
characters: &[&'a StarWarsChar],
|
||||
map_to: F,
|
||||
) -> Result<Connection<usize, T>>
|
||||
where
|
||||
F: Fn(&'a StarWarsChar) -> T,
|
||||
T: OutputType,
|
||||
{
|
||||
query(
|
||||
after,
|
||||
before,
|
||||
@ -205,14 +226,15 @@ async fn query_characters(
|
||||
}
|
||||
|
||||
let mut connection = Connection::new(start > 0, end < characters.len());
|
||||
connection.append(
|
||||
|
||||
connection.edges.extend(
|
||||
slice
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, item)| Edge::new(start + idx, *item)),
|
||||
.map(|(idx, item)| Edge::new(start + idx, (map_to)(*item))),
|
||||
);
|
||||
|
||||
FieldResult::Ok(connection)
|
||||
Ok::<_, Error>(connection)
|
||||
},
|
||||
)
|
||||
.await
|
||||
|
@ -9,5 +9,5 @@ env_logger = "0.9"
|
||||
futures-util = { version = "0.3.7", default-features = false, features = ["std"] }
|
||||
log = "0.4"
|
||||
parking_lot = "0.12"
|
||||
tokio = { version = "1.16", features = ["sync"] }
|
||||
tokio = { version = "1.13.1", features = ["sync"] }
|
||||
tokio-stream = { version = "0.1.8", features = ["time"] }
|
||||
|
@ -9,4 +9,4 @@ actix-web = "4"
|
||||
|
||||
env_logger = "0.9"
|
||||
log = "0.4"
|
||||
tokio = { version = "1.16", features = ["signal"] }
|
||||
tokio = { version = "1.13.1", features = ["signal"] }
|
||||
|
Loading…
Reference in New Issue
Block a user