2020-03-05 13:34:31 +00:00
|
|
|
use super::StarWars;
|
2020-03-07 10:03:19 +00:00
|
|
|
use async_graphql::Context;
|
2020-03-05 13:34:31 +00:00
|
|
|
|
|
|
|
#[async_graphql::Enum(desc = "One of the films in the Star Wars Trilogy")]
|
|
|
|
pub enum Episode {
|
|
|
|
#[item(desc = "Released in 1977.")]
|
2020-03-09 12:00:57 +00:00
|
|
|
NewHope,
|
2020-03-05 13:34:31 +00:00
|
|
|
|
|
|
|
#[item(desc = "Released in 1980.")]
|
2020-03-09 12:00:57 +00:00
|
|
|
Empire,
|
2020-03-05 13:34:31 +00:00
|
|
|
|
|
|
|
#[item(desc = "Released in 1983.")]
|
2020-03-09 12:00:57 +00:00
|
|
|
Jedi,
|
2020-03-05 13:34:31 +00:00
|
|
|
}
|
|
|
|
|
2020-03-07 10:03:19 +00:00
|
|
|
pub struct Human(usize);
|
2020-03-05 13:34:31 +00:00
|
|
|
|
|
|
|
#[async_graphql::Object(desc = "A humanoid creature in the Star Wars universe.")]
|
2020-03-07 10:03:19 +00:00
|
|
|
impl Human {
|
2020-03-05 13:34:31 +00:00
|
|
|
#[field(desc = "The id of the human.")]
|
2020-03-09 10:10:41 +00:00
|
|
|
async fn id(&self, ctx: &Context<'_>) -> &str {
|
2020-03-07 10:03:19 +00:00
|
|
|
ctx.data::<StarWars>().chars[self.0].id
|
2020-03-05 13:34:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[field(desc = "The name of the human.")]
|
2020-03-07 10:03:19 +00:00
|
|
|
async fn name(&self, ctx: &Context<'_>) -> &str {
|
|
|
|
ctx.data::<StarWars>().chars[self.0].name
|
2020-03-05 13:34:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[field(desc = "The friends of the human, or an empty list if they have none.")]
|
2020-03-07 10:03:19 +00:00
|
|
|
async fn friends(&self, ctx: &Context<'_>) -> Vec<Character> {
|
|
|
|
ctx.data::<StarWars>().chars[self.0]
|
2020-03-05 13:34:31 +00:00
|
|
|
.friends
|
|
|
|
.iter()
|
2020-03-07 10:03:19 +00:00
|
|
|
.map(|id| Human(*id).into())
|
2020-03-05 13:34:31 +00:00
|
|
|
.collect()
|
|
|
|
}
|
|
|
|
|
2020-03-09 12:00:57 +00:00
|
|
|
#[field(desc = "Which movies they appear in.")]
|
2020-03-07 10:03:19 +00:00
|
|
|
async fn appears_in<'a>(&self, ctx: &'a Context<'_>) -> &'a [Episode] {
|
|
|
|
&ctx.data::<StarWars>().chars[self.0].appears_in
|
2020-03-05 13:34:31 +00:00
|
|
|
}
|
|
|
|
|
2020-03-09 12:00:57 +00:00
|
|
|
#[field(desc = "The home planet of the human, or null if unknown.")]
|
2020-03-07 10:03:19 +00:00
|
|
|
async fn home_planet<'a>(&self, ctx: &'a Context<'_>) -> &'a Option<&'a str> {
|
|
|
|
&ctx.data::<StarWars>().chars[self.0].home_planet
|
2020-03-05 13:34:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-07 10:03:19 +00:00
|
|
|
pub struct Droid(usize);
|
2020-03-05 13:34:31 +00:00
|
|
|
|
|
|
|
#[async_graphql::Object(desc = "A mechanical creature in the Star Wars universe.")]
|
2020-03-07 10:03:19 +00:00
|
|
|
impl Droid {
|
2020-03-05 13:34:31 +00:00
|
|
|
#[field(desc = "The id of the droid.")]
|
2020-03-07 10:03:19 +00:00
|
|
|
async fn id(&self, ctx: &Context<'_>) -> &str {
|
|
|
|
ctx.data::<StarWars>().chars[self.0].id
|
2020-03-05 13:34:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[field(desc = "The name of the droid.")]
|
2020-03-07 10:03:19 +00:00
|
|
|
async fn name(&self, ctx: &Context<'_>) -> &str {
|
|
|
|
ctx.data::<StarWars>().chars[self.0].name
|
2020-03-05 13:34:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[field(desc = "The friends of the droid, or an empty list if they have none.")]
|
2020-03-07 10:03:19 +00:00
|
|
|
async fn friends(&self, ctx: &Context<'_>) -> Vec<Character> {
|
|
|
|
ctx.data::<StarWars>().chars[self.0]
|
2020-03-05 13:34:31 +00:00
|
|
|
.friends
|
|
|
|
.iter()
|
2020-03-07 10:03:19 +00:00
|
|
|
.map(|id| Droid(*id).into())
|
2020-03-05 13:34:31 +00:00
|
|
|
.collect()
|
|
|
|
}
|
|
|
|
|
2020-03-09 12:00:57 +00:00
|
|
|
#[field(desc = "Which movies they appear in.")]
|
2020-03-07 10:03:19 +00:00
|
|
|
async fn appears_in<'a>(&self, ctx: &'a Context<'_>) -> &'a [Episode] {
|
|
|
|
&ctx.data::<StarWars>().chars[self.0].appears_in
|
2020-03-05 13:34:31 +00:00
|
|
|
}
|
|
|
|
|
2020-03-09 12:00:57 +00:00
|
|
|
#[field(desc = "The primary function of the droid.")]
|
2020-03-07 10:03:19 +00:00
|
|
|
async fn primary_function<'a>(&self, ctx: &'a Context<'_>) -> &'a Option<&'a str> {
|
|
|
|
&ctx.data::<StarWars>().chars[self.0].primary_function
|
2020-03-05 13:34:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-07 10:03:19 +00:00
|
|
|
pub struct QueryRoot;
|
2020-03-05 13:34:31 +00:00
|
|
|
|
|
|
|
#[async_graphql::Object]
|
|
|
|
impl QueryRoot {
|
|
|
|
#[field]
|
|
|
|
async fn hero(
|
|
|
|
&self,
|
2020-03-07 10:03:19 +00:00
|
|
|
ctx: &Context<'_>,
|
2020-03-05 13:34:31 +00:00
|
|
|
#[arg(
|
|
|
|
desc = "If omitted, returns the hero of the whole saga. If provided, returns the hero of that particular episode."
|
|
|
|
)]
|
|
|
|
episode: Episode,
|
2020-03-07 10:03:19 +00:00
|
|
|
) -> Character {
|
2020-03-09 12:00:57 +00:00
|
|
|
if episode == Episode::Empire {
|
2020-03-07 10:03:19 +00:00
|
|
|
Human(ctx.data::<StarWars>().luke).into()
|
2020-03-06 15:58:43 +00:00
|
|
|
} else {
|
2020-03-07 10:03:19 +00:00
|
|
|
Droid(ctx.data::<StarWars>().artoo).into()
|
2020-03-05 13:34:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[field]
|
2020-03-07 10:03:19 +00:00
|
|
|
async fn human(
|
|
|
|
&self,
|
|
|
|
ctx: &Context<'_>,
|
|
|
|
#[arg(desc = "id of the human")] id: String,
|
|
|
|
) -> Option<Human> {
|
|
|
|
ctx.data::<StarWars>().human(&id).map(|id| Human(id))
|
2020-03-05 13:34:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[field]
|
2020-03-07 10:03:19 +00:00
|
|
|
async fn droid(
|
|
|
|
&self,
|
|
|
|
ctx: &Context<'_>,
|
|
|
|
#[arg(desc = "id of the droid")] id: String,
|
|
|
|
) -> Option<Droid> {
|
|
|
|
ctx.data::<StarWars>().droid(&id).map(|id| Droid(id))
|
2020-03-05 13:34:31 +00:00
|
|
|
}
|
|
|
|
}
|
2020-03-06 15:58:43 +00:00
|
|
|
|
|
|
|
#[async_graphql::Interface(
|
2020-03-07 10:03:19 +00:00
|
|
|
field(name = "id", type = "&str", context),
|
|
|
|
field(name = "name", type = "&str", context),
|
|
|
|
field(name = "friends", type = "Vec<Character>", context),
|
2020-03-09 12:00:57 +00:00
|
|
|
field(name = "appears_in", type = "&'ctx [Episode]", context)
|
2020-03-06 15:58:43 +00:00
|
|
|
)]
|
2020-03-07 10:03:19 +00:00
|
|
|
pub struct Character(Human, Droid);
|