From 0a201cd86001211e4da8402ff009967fd1132f7a Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sat, 9 Jul 2022 23:35:09 +0100 Subject: [PATCH] update async-graphql deps --- Cargo.lock | 80 ++++++--- auth/casbin/Cargo.toml | 6 +- graphql/async-graphql/Cargo.toml | 8 +- graphql/async-graphql/src/star_wars/mod.rs | 76 +++++---- graphql/async-graphql/src/star_wars/model.rs | 168 +++++++++++-------- server-sent-events/Cargo.toml | 2 +- shutdown-server/Cargo.toml | 2 +- 7 files changed, 212 insertions(+), 130 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8f1c167..01ac7ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/auth/casbin/Cargo.toml b/auth/casbin/Cargo.toml index 8afe33c..e22203c 100644 --- a/auth/casbin/Cargo.toml +++ b/auth/casbin/Cargo.toml @@ -5,6 +5,6 @@ edition = "2021" [dependencies] actix-web = "4" -casbin = "2.0.9" -loge = {version = "0.4", default-features = false, features = ["colored", "chrono"]} -tokio = { version = "1.16.1", features = ["sync"] } +casbin = "2" +loge = { version = "0.4", default-features = false, features = ["colored", "chrono"] } +tokio = { version = "1.13.1", features = ["sync"] } diff --git a/graphql/async-graphql/Cargo.toml b/graphql/async-graphql/Cargo.toml index a626f97..d316754 100644 --- a/graphql/async-graphql/Cargo.toml +++ b/graphql/async-graphql/Cargo.toml @@ -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" diff --git a/graphql/async-graphql/src/star_wars/mod.rs b/graphql/async-graphql/src/star_wars/mod.rs index eb1b7a2..7295ac3 100644 --- a/graphql/async-graphql/src/star_wars/mod.rs +++ b/graphql/async-graphql/src/star_wars/mod.rs @@ -1,17 +1,18 @@ use std::collections::HashMap; use async_graphql::{EmptyMutation, EmptySubscription, Schema}; -use model::Episode; use slab::Slab; -pub type StarWarsSchema = Schema; - mod model; -pub use self::model::QueryRoot; +use model::Episode; +pub use model::QueryRoot; + +pub type StarWarsSchema = Schema; pub struct StarWarsChar { id: &'static str, name: &'static str, + is_human: bool, friends: Vec, appears_in: Vec, home_planet: Option<&'static str>, @@ -22,8 +23,7 @@ pub struct StarWars { luke: usize, artoo: usize, chars: Slab, - 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 { - 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 { - 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 { - 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 { - 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() } } diff --git a/graphql/async-graphql/src/star_wars/model.rs b/graphql/async-graphql/src/star_wars/model.rs index d8a871e..d09312b 100644 --- a/graphql/async-graphql/src/star_wars/model.rs +++ b/graphql/async-graphql/src/star_wars/model.rs @@ -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::().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::().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 { - ctx.data_unchecked::().chars[self.0] - .friends - .iter() - .map(|id| Human(*id).into()) + async fn friends<'ctx>(&self, ctx: &Context<'ctx>) -> Vec> { + ctx.data_unchecked::() + .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::().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::().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::().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::().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 { - ctx.data_unchecked::().chars[self.0] - .friends - .iter() - .map(|id| Droid(*id).into()) + async fn friends<'ctx>(&self, ctx: &Context<'ctx>) -> Vec> { + ctx.data_unchecked::() + .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::().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::().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::().luke).into() - } else { - Droid(ctx.data_unchecked::().artoo).into() + episode: Option, + ) -> Character<'a> { + let star_wars = ctx.data_unchecked::(); + + match episode { + Some(episode_name) => { + if episode_name == Episode::Empire { + Human(star_wars.chars.get(star_wars.luke).unwrap()).into() + } else { + Droid(star_wars.chars.get(star_wars.artoo).unwrap()).into() + } + } + + None => Human(star_wars.chars.get(star_wars.luke).unwrap()).into(), } } - async fn human( + async fn human<'a>( &self, - ctx: &Context<'_>, + ctx: &Context<'a>, #[graphql(desc = "id of the human")] id: String, - ) -> Option { + ) -> Option> { ctx.data_unchecked::().human(&id).map(Human) } - async fn humans( + async fn humans<'a>( &self, - ctx: &Context<'_>, + ctx: &Context<'a>, after: Option, before: Option, first: Option, last: Option, - ) -> FieldResult> { + ) -> Result>> { let humans = ctx.data_unchecked::().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 { + ) -> Option> { ctx.data_unchecked::().droid(&id).map(Droid) } - async fn droids( + async fn droids<'a>( &self, - ctx: &Context<'_>, + ctx: &Context<'a>, after: Option, before: Option, first: Option, last: Option, - ) -> FieldResult> { + ) -> Result>> { let droids = ctx.data_unchecked::().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"), - field(name = "appears_in", type = "&'ctx [Episode]") + field(name = "friends", type = "Vec>"), + 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, before: Option, first: Option, last: Option, - characters: &[usize], -) -> FieldResult> { + characters: &[&'a StarWarsChar], + map_to: F, +) -> Result> +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 diff --git a/server-sent-events/Cargo.toml b/server-sent-events/Cargo.toml index dc3df48..4f74803 100644 --- a/server-sent-events/Cargo.toml +++ b/server-sent-events/Cargo.toml @@ -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"] } diff --git a/shutdown-server/Cargo.toml b/shutdown-server/Cargo.toml index a968111..1e206e7 100644 --- a/shutdown-server/Cargo.toml +++ b/shutdown-server/Cargo.toml @@ -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"] }