Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add skip_default_scalars option #437

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,20 @@ error[E0412]: cannot find type `URI` in module `super`
crate::repo_view::URI
```

If you would like to customize how some of the five default scalars are represented, you can use the `skip_default_scalars` option. You will then have to define your own types for them like for custom scalars.

```rust
use graphql_client::GraphQLQuery;

#[derive(GraphQLQuery)]
#[graphql(
schema_path = "tests/unions/union_schema.graphql",
query_path = "tests/unions/union_query.graphql",
skip_default_scalars
)]
struct UnionQuery;
```

## Deprecations

The generated code has support for [`@deprecated`](http://facebook.github.io/graphql/June2018/#sec-Field-Deprecation)
Expand Down
26 changes: 17 additions & 9 deletions graphql_client_codegen/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,21 @@ pub(crate) fn response_for_query(
&query,
);

let default_scalar_definitions = if *options.skip_default_scalars() {
quote!()
} else {
quote! {
#[allow(dead_code)]
type Boolean = bool;
#[allow(dead_code)]
type Float = f64;
#[allow(dead_code)]
type Int = i64;
#[allow(dead_code)]
type ID = String;
}
};

let variables_struct =
generate_variables_struct(operation_id, &variable_derives, options, &query);

Expand All @@ -46,14 +61,7 @@ pub(crate) fn response_for_query(
use serde::{Serialize, Deserialize};
use super::*;

#[allow(dead_code)]
type Boolean = bool;
#[allow(dead_code)]
type Float = f64;
#[allow(dead_code)]
type Int = i64;
#[allow(dead_code)]
type ID = String;
#default_scalar_definitions

#(#scalar_definitions)*

Expand Down Expand Up @@ -147,7 +155,7 @@ fn generate_scalar_definitions<'a, 'schema: 'a>(
query: BoundQuery<'schema>,
) -> impl Iterator<Item = TokenStream> + 'a {
all_used_types
.scalars(query.schema)
.scalars(query.schema, *options.skip_default_scalars())
.map(move |(_id, scalar)| {
let ident = syn::Ident::new(
options.normalization().scalar_name(&scalar.name).as_ref(),
Expand Down
13 changes: 13 additions & 0 deletions graphql_client_codegen/src/codegen_options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ pub struct GraphQLClientCodegenOptions {
schema_file: Option<PathBuf>,
/// Normalization pattern for query types and names.
normalization: Normalization,
/// Don't define default scalar types and let the user define them instead.
skip_default_scalars: bool,
/// Custom scalar definitions module path
custom_scalars_module: Option<syn::Path>,
/// List of externally defined enum types. Type names must match those used in the schema exactly.
Expand All @@ -64,6 +66,7 @@ impl GraphQLClientCodegenOptions {
query_file: Default::default(),
schema_file: Default::default(),
normalization: Normalization::None,
skip_default_scalars: Default::default(),
custom_scalars_module: Default::default(),
extern_enums: Default::default(),
fragments_other_variant: Default::default(),
Expand Down Expand Up @@ -188,6 +191,16 @@ impl GraphQLClientCodegenOptions {
&self.normalization
}

/// Set the graphql client codegen option's skip default scalars value.
pub fn set_skip_default_scalars(&mut self, skip_default_scalars: bool) {
self.skip_default_scalars = skip_default_scalars
}

/// Get a reference to the graphql client codegen option's skip default scalars value.
pub fn skip_default_scalars(&self) -> &bool {
&self.skip_default_scalars
}

/// Get the custom scalar definitions module
pub fn custom_scalars_module(&self) -> Option<&syn::Path> {
self.custom_scalars_module.as_ref()
Expand Down
5 changes: 4 additions & 1 deletion graphql_client_codegen/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -637,12 +637,15 @@ impl UsedTypes {
pub(crate) fn scalars<'s, 'a: 's>(
&'s self,
schema: &'a Schema,
include_default: bool,
) -> impl Iterator<Item = (ScalarId, &'a StoredScalar)> + 's {
self.types
.iter()
.filter_map(TypeId::as_scalar_id)
.map(move |scalar_id| (scalar_id, schema.get_scalar(scalar_id)))
.filter(|(_id, scalar)| !crate::schema::DEFAULT_SCALARS.contains(&scalar.name.as_str()))
.filter(move |(_id, scalar)| {
include_default || !crate::schema::DEFAULT_SCALARS.contains(&scalar.name.as_str())
})
}

pub(crate) fn enums<'a, 'schema: 'a>(
Expand Down
4 changes: 4 additions & 0 deletions graphql_query_derive/src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ pub fn extract_normalization(ast: &syn::DeriveInput) -> Result<Normalization, sy
.map_err(|_| syn::Error::new_spanned(ast, NORMALIZATION_ERROR))
}

pub fn extract_skip_default_scalars(ast: &syn::DeriveInput) -> bool {
ident_exists(ast, "skip_default_scalars").is_ok()
}

pub fn extract_fragments_other_variant(ast: &syn::DeriveInput) -> bool {
extract_attr(ast, "fragments_other_variant")
.ok()
Expand Down
2 changes: 2 additions & 0 deletions graphql_query_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,15 @@ fn build_graphql_client_derive_options(
) -> Result<GraphQLClientCodegenOptions, syn::Error> {
let variables_derives = attributes::extract_attr(input, "variables_derives").ok();
let response_derives = attributes::extract_attr(input, "response_derives").ok();
let skip_default_scalars: bool = attributes::extract_skip_default_scalars(input);
let custom_scalars_module = attributes::extract_attr(input, "custom_scalars_module").ok();
let extern_enums = attributes::extract_attr_list(input, "extern_enums").ok();
let fragments_other_variant: bool = attributes::extract_fragments_other_variant(input);
let skip_serializing_none: bool = attributes::extract_skip_serializing_none(input);

let mut options = GraphQLClientCodegenOptions::new(CodegenMode::Derive);
options.set_query_file(query_path);
options.set_skip_default_scalars(skip_default_scalars);
options.set_fragments_other_variant(fragments_other_variant);
options.set_skip_serializing_none(skip_serializing_none);

Expand Down