negezor / shikimori-rust

A Rust 🦀 wrapper for Shikimori API
MIT License
0 stars 0 forks source link

cynic::QueryFragment tries to use default schema #1

Open t1ltxz-gxd opened 2 months ago

t1ltxz-gxd commented 2 months ago

Build output:

error: This derive is trying to use the default schema, but it doesn't look like you've registered any schemas.  See the cynic documentation on regsistering schemas if you need help.
  --> shikimori/src/main.rs:20:10
   |
20 | #[derive(cynic::QueryFragment, Debug)]
   |          ^^^^^^^^^^^^^^^^^^^^
   |
   = note: this error originates in the derive macro `cynic::QueryFragment` (in Nightly builds, run with -Z macro-backtrace for more info)
error: This derive is trying to use the default schema, but it doesn't look like you've registered any schemas.  See the cynic documentation on regsistering schemas if you need help.
  --> shikimori/src/main.rs:27:10
   |
27 | #[derive(cynic::QueryFragment, Debug)]
   |          ^^^^^^^^^^^^^^^^^^^^
   |
   = note: this error originates in the derive macro `cynic::QueryFragment` (in Nightly builds, run with -Z macro-backtrace for more info)
   error[E0599]: no function or associated item named `build` found for struct `AnimesQuery` in the current scope
  --> shikimori/src/main.rs:42:29
   |
22 | pub struct AnimesQuery {
   | ---------------------- function or associated item `build` not found for this struct
...
42 |         .query(AnimesQuery::build(AnimesQueryVariables {
   |                             ^^^^^ function or associated item not found in `AnimesQuery`
   |
   = help: items from traits can only be used if the trait is implemented and in scope
   = note: the following traits define an item `build`, perhaps you need to implement one of them:
           candidate #1: `QueryBuilder`
           candidate #2: `MutationBuilder`
           candidate #3: `SubscriptionBuilder`

My code taken from the example use case:

use chrono::{DateTime, Utc};

use shikimori::{client::ClientBuilder,
                cynic,
                graphql::{
                    anime::AnimeKind,
                    types::EntityOrder,
                    scalars::{AnimeStatusString},
                    schema
                }
};

#[derive(cynic::QueryVariables, Debug)]
pub struct AnimesQueryVariables {
    pub page: i32,
    pub status: AnimeStatusString,
    pub order: EntityOrder,
}

#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Query", variables = "AnimesQueryVariables")]
pub struct AnimesQuery {
    #[arguments(censored: false, page: $page, status: $status, order: $order)]
    pub animes: Vec<Anime>,
}

#[derive(cynic::QueryFragment, Debug)]
pub struct Anime {
    pub id: cynic::Id,
    pub franchise: Option<String>,
    pub episodes: i32,
    pub kind: Option<AnimeKind>,
    pub next_episode_at: Option<DateTime<Utc>>,
    pub url: String,
}

#[tokio::main]
async fn main() {
    let client = ClientBuilder::new().build();

    let response = client
        .query(AnimesQuery::build(AnimesQueryVariables {
            page: 1,
            status: AnimeStatusString::new("ongoing"),
            order: EntityOrder::Popularity,
        }))
        .await;

    dbg!(&response);
}

Here I only changed use scalars::{StatusString} to scalars::{AnimeStatusString}, cause the code was refactored but you forgot to update the example =) img img

negezor commented 2 months ago

The library is trying to simply be representations of the API, which is still unstable. After the changes, does the example work?

t1ltxz-gxd commented 2 months ago

I changed it a little bit and now I have Meitantei Conan as the answer. Below is the code that is currently working

use chrono::{DateTime, Utc};

use shikimori::{client::ClientBuilder,
                cynic,
                cynic::{Id, QueryFragment, QueryVariables, QueryBuilder},
                graphql::{
                    anime::AnimeKind,
                    types::EntityOrder,
                    scalars::{AnimeStatusString},
                    schema
                }
};

#[derive(QueryVariables, Debug)]
pub struct AnimesQueryVariables {
    pub page: i32,
    pub status: AnimeStatusString,
    pub order: EntityOrder,
}

#[derive(QueryFragment, Debug)]
#[cynic(graphql_type = "Query", variables = "AnimesQueryVariables", schema_path = "../schema.graphql")]
pub struct AnimesQuery {
    #[arguments(censored: false, page: $page, status: $status, order: $order)]
    pub animes: Vec<Anime>,
}

#[derive(QueryFragment, Debug)]
#[cynic(graphql_type = "Anime", variables = "AnimesQueryVariables", schema_path = "../schema.graphql")]
pub struct Anime {
    pub id: Id,
    pub franchise: Option<String>,
    pub episodes: i32,
    pub kind: Option<AnimeKind>,
    pub next_episode_at: Option<DateTime<Utc>>,
    pub url: String,
}

#[tokio::main]
async fn main() {
    let client = ClientBuilder::new().build();

    let response = client
        .query(AnimesQuery::build(AnimesQueryVariables {
            page: 1,
            status: AnimeStatusString::new("ongoing"),
            order: EntityOrder::Popularity,
        }))
        .await;

    dbg!(&response);
}

Console log:

Finished dev [unoptimized + debuginfo] target(s) in 0.04s
     Running `target/debug/shikimori`
[shikimori/src/main.rs:51:5] &response = Ok(
    GraphQlResponse {
        data: Some(
            AnimesQuery {
                animes: [
                    Anime {
                        id: Id(
                            "21",
                        ),
                        franchise: Some(
                            "one_piece",
                        ),
                        episodes: 0,
                        kind: Some(
                            Tv,
                        ),
                        next_episode_at: Some(
                            2024-05-05T00:30:00Z,
                        ),
                        url: "https://shikimori.one/animes/21-one-piece",
                    },
                    Anime {
                        id: Id(
                            "235",
                        ),
                        franchise: Some(
                            "detective_conan",
                        ),
                        episodes: 0,
                        kind: Some(
                            Tv,
                        ),
                        next_episode_at: Some(
                            2024-05-04T09:00:00Z,
                        ),
                        url: "https://shikimori.one/animes/z235-meitantei-conan",
                    },
                ],
            },
        ),
        errors: None,
    },
)

Process finished with exit code 0
t1ltxz-gxd commented 2 months ago

I had to download schema.graphql from shikimori to get the code to work

negezor commented 2 months ago

I've been thinking about how to make this point better, but haven't come to a conclusion yet. Maybe I should create a feature that will export the following code:

#[cfg(feature = "codegen")]
pub fn register_schema() {
    cynic_codegen::register_schema("shikimori")
        .from_sdl(include_str!("./schema.graphql"))
        .unwrap()
        .as_default()
        .unwrap();
}
t1ltxz-gxd commented 2 months ago

in my opinion, the build should affect derive so that library users do not need to download the schema for their code to work

t1ltxz-gxd commented 2 months ago

I noticed that r.n. there is a problem with the error Unresolved import: shikimori::graphql::schema [E0432]. Build should generate an exportable module schema for this to solve the problem 🐣