// Generated by moongql from library.mbt. Edit those files, not this one.

///|
pub fn register(schema : @moongql.Schema, resolvers : @moongql.Resolvers) -> Unit {
  if schema.scalar_by_name("Int64") is None {
    schema.scalar("Int64")
  }
  let gql_author = 
    schema.object("Author", description="Someone who writes books")
  gql_author.field("id", NonNull(Scalar("Int64")))
  gql_author.field("name", NonNull(Scalar("String")))
  schema.enum_(
    "Status",
    ["Draft", "Published"],
    description="Where a book stands",
  )
  let gql_book = schema.object("Book")
  gql_book.field("id", NonNull(Scalar("Int64")))
  gql_book.field("title", NonNull(Scalar("String")))
  gql_book.field("status", NonNull(Named("Status")))
  gql_book.field("authorId", NonNull(Scalar("Int64")))
  gql_book.field(
    "isbn",
    Scalar("String"),
    deprecation_reason="ISBNs are going away",
  )
  let gql_newbook = schema.input("NewBook")
  gql_newbook.field("title", NonNull(Scalar("String")))
  gql_newbook.field("authorId", NonNull(Scalar("Int64")))
  gql_newbook.field("status", Named("Status"))
  let gql_magazine = schema.object("Magazine")
  gql_magazine.field("id", NonNull(Scalar("Int64")))
  gql_magazine.field("title", NonNull(Scalar("String")))
  gql_magazine.field("issue", NonNull(Scalar("Int")))
  let gql_work = schema.interface("Work", description="Anything on the shelf")
  gql_work.field("id", NonNull(Scalar("Int64")))
  gql_work.field("title", NonNull(Scalar("String")))
  gql_book.implements("Work")
  gql_magazine.implements("Work")
  schema.union("Hit", ["Author", "Book"])
  let gql_query = match schema.type_by_name(schema.query) {
    Some(t) => t
    None => schema.object(schema.query)
  }
  let gql_mutation = match schema.mutation {
    Some(n) => {
      match schema.type_by_name(n) {
        Some(t) => t
        None => schema.object(n)
      }
    }
    None => {
      schema.set_mutation("Mutation")
      schema.object("Mutation")
    }
  }
  gql_author.field_args(
    "books",
    [("first", Scalar("Int"))],
    NonNull(ListOf(NonNull(Named("Book")))),
    description="Their books, at most `first`",
  )
  resolvers.field(
    "Author", "books", info => {
      let self_ :Author = @moongql.FromGql::from_gql(info.parent)
      @moongql.ToGql::to_gql(Author::books(self_, first?=info.read("first")))
    },
  )
  gql_author.field("contact", NonNull(Scalar("String")))
  resolvers.field(
    "Author", "contact", info => {
      let self_ :Author = @moongql.FromGql::from_gql(info.parent)
      @moongql.ToGql::to_gql(Author::contact(self_))
    },
  )
  gql_book.field("author", Named("Author"))
  resolvers.field(
    "Book", "author", info => {
      let self_ :Book = @moongql.FromGql::from_gql(info.parent)
      @moongql.ToGql::to_gql(Book::author(self_))
    },
  )
  gql_query.field_args(
    "author",
    [("id", NonNull(Scalar("Int64")))],
    Named("Author"),
  )
  resolvers.field(
    gql_query.name, "author", info => {
      @moongql.ToGql::to_gql(author(info.read("id")))
    },
  )
  gql_query.field_args(
    "books",
    [("status", Named("Status"))],
    NonNull(ListOf(NonNull(Named("Book")))),
    description="Every book, or those in one state",
  )
  resolvers.field(
    gql_query.name, "books", info => {
      @moongql.ToGql::to_gql(books(status?=info.read("status")))
    },
  )
  gql_query.field("works", NonNull(ListOf(NonNull(Named("Work")))))
  resolvers.field(gql_query.name, "works", _ => @moongql.ToGql::to_gql(works()))
  gql_query.field_args(
    "search",
    [("text", NonNull(Scalar("String")))],
    NonNull(ListOf(NonNull(Named("Hit")))),
    description="Authors and titles that contain `text`",
  )
  resolvers.field(
    gql_query.name, "search", info => {
      @moongql.ToGql::to_gql(search(info.read("text")))
    },
  )
  gql_mutation.field_args(
    "addBook",
    [("input", NonNull(Named("NewBook")))],
    NonNull(Named("Book")),
  )
  resolvers.field(
    gql_mutation.name, "addBook", info => {
      try {
        @moongql.ToGql::to_gql(add_book(info.read("input")))
      } catch{
        e => raise  @moongql.field_error(e)
      }
    },
  )
}

///|
pub impl @moongql.ToGql for Author with fn to_gql(self) {
  {
    "__typename": "Author",
    "id": @moongql.ToGql::to_gql(self.id),
    "name": @moongql.ToGql::to_gql(self.name),
    "email": @moongql.ToGql::to_gql(self.email),
  }
}

///|
pub impl @moongql.FromGql for Author with fn from_gql(v) {
  Author::{
    id: @moongql.read(v, "id"),
    name: @moongql.read(v, "name"),
    email: @moongql.read(v, "email"),
  }
}

///|
pub extend Author with @moongql.ToGql::{ to_gql }

///|
pub extend Author with @moongql.FromGql::{ from_gql }

///|
pub impl @moongql.ToGql for Status with fn to_gql(self) {
  match self {
    Draft => "Draft"
    Published => "Published"
  }
}

///|
pub impl @moongql.FromGql for Status with fn from_gql(v) {
  match v {
    String("Draft") => Draft
    String("Published") => Published
    other => raise  @moongql.ResolverError::expected("Status", other)
  }
}

///|
pub extend Status with @moongql.ToGql::{ to_gql }

///|
pub extend Status with @moongql.FromGql::{ from_gql }

///|
pub impl @moongql.ToGql for Book with fn to_gql(self) {
  {
    "__typename": "Book",
    "id": @moongql.ToGql::to_gql(self.id),
    "title": @moongql.ToGql::to_gql(self.title),
    "status": @moongql.ToGql::to_gql(self.status),
    "authorId": @moongql.ToGql::to_gql(self.author_id),
    "isbn": @moongql.ToGql::to_gql(self.code),
  }
}

///|
pub impl @moongql.FromGql for Book with fn from_gql(v) {
  Book::{
    id: @moongql.read(v, "id"),
    title: @moongql.read(v, "title"),
    status: @moongql.read(v, "status"),
    author_id: @moongql.read(v, "authorId"),
    code: @moongql.read(v, "isbn"),
  }
}

///|
pub extend Book with @moongql.ToGql::{ to_gql }

///|
pub extend Book with @moongql.FromGql::{ from_gql }

///|
pub impl @moongql.ToGql for NewBook with fn to_gql(self) {
  {
    "title": @moongql.ToGql::to_gql(self.title),
    "authorId": @moongql.ToGql::to_gql(self.author_id),
    "status": @moongql.ToGql::to_gql(self.status),
  }
}

///|
pub impl @moongql.FromGql for NewBook with fn from_gql(v) {
  NewBook::{
    title: @moongql.read(v, "title"),
    author_id: @moongql.read(v, "authorId"),
    status: @moongql.read(v, "status"),
  }
}

///|
pub extend NewBook with @moongql.ToGql::{ to_gql }

///|
pub extend NewBook with @moongql.FromGql::{ from_gql }

///|
pub impl @moongql.ToGql for Magazine with fn to_gql(self) {
  {
    "__typename": "Magazine",
    "id": @moongql.ToGql::to_gql(self.id),
    "title": @moongql.ToGql::to_gql(self.title),
    "issue": @moongql.ToGql::to_gql(self.issue),
  }
}

///|
pub impl @moongql.FromGql for Magazine with fn from_gql(v) {
  Magazine::{
    id: @moongql.read(v, "id"),
    title: @moongql.read(v, "title"),
    issue: @moongql.read(v, "issue"),
  }
}

///|
pub extend Magazine with @moongql.ToGql::{ to_gql }

///|
pub extend Magazine with @moongql.FromGql::{ from_gql }

///|
pub impl @moongql.ToGql for Work with fn to_gql(self) {
  match self {
    Printed(v) => @moongql.ToGql::to_gql(v)
    Periodical(v) => @moongql.ToGql::to_gql(v)
  }
}

///|
pub impl @moongql.FromGql for Work with fn from_gql(v) {
  match v {
    { "__typename": String("Book"), .. } => 
      Printed(@moongql.FromGql::from_gql(v))
    { "__typename": String("Magazine"), .. } => 
      Periodical(@moongql.FromGql::from_gql(v))
    other => raise  @moongql.ResolverError::expected("Work", other)
  }
}

///|
pub extend Work with @moongql.ToGql::{ to_gql }

///|
pub extend Work with @moongql.FromGql::{ from_gql }

///|
pub impl @moongql.ToGql for Hit with fn to_gql(self) {
  match self {
    Writer(v) => @moongql.ToGql::to_gql(v)
    Title(v) => @moongql.ToGql::to_gql(v)
  }
}

///|
pub impl @moongql.FromGql for Hit with fn from_gql(v) {
  match v {
    { "__typename": String("Author"), .. } => 
      Writer(@moongql.FromGql::from_gql(v))
    { "__typename": String("Book"), .. } => Title(@moongql.FromGql::from_gql(v))
    other => raise  @moongql.ResolverError::expected("Hit", other)
  }
}

///|
pub extend Hit with @moongql.ToGql::{ to_gql }

///|
pub extend Hit with @moongql.FromGql::{ from_gql }