I noticed that `juniper` fails to build if the `"expose-test-schema"` feature is enabled without also enabling `"serde_json"`. I guess it might make sense to add it as a dependency so people don't have to check this file to figure that out!
Co-authored-by: Christian Legnitto <LegNeato@users.noreply.github.com>
* Implement `std::error::Error` for all error types
* Fix copy-paste
* Implement `Display` for `Value`
This is required for implementing `Display` for `FieldError`
* Implement `std::error::Error` for `FieldError`
This required removing `impl From<T> for FieldError where T: Display`
because it would otherwise cause a conflicting implementation. That is
because `impl From<T> for T` already exists.
Instead I added `impl From<String> for FieldError` and `impl From<&str>
for FieldError` which should cover most use cases of the previous
`impl`. I also added `FieldError::from_error` so users can convert
from any error they may have.
* Bring back `impl<T: Display, S> From<T> for FieldError<S>`
We cannot have this and `impl<S> std::error::Error for FieldError<S>` so
we agreed this is more valuable. More context https://github.com/graphql-rust/juniper/pull/419
* Write errors without allocations
there is still some weirdness going on. Running async and
non-async tests in `integration_tests/*` works, but running it
from `integration_tests` does not.
* Validate variables of the executed operation only
* Use `unreachable!` in `validate_var_defs`.
Use `unreachable!` instead of `panic!` on invalid variable types,
since thay have already been checked during document validation.
* Fix formatting in `validation/input_value.rs`
The `uuid` maintainers have started releasing in the `0.8` version train. I've relaxed the version requirements on `juniper`'s dependencies to allow juniper users to specify a different version in their `Cargo.toml` and still have the integration work.
* Implement GraphQLTypeAsync for Arc
I'm building a GraphQL API using Juniper that proxies another GraphQL
API. It does a large fetch upfront from the underlying GraphQL API,
transforms it into a different format and then implements some
resolvers that do some further filtering.
One of these resolvers ends up looking like:
```
async fn items(&self, ...) -> Vec<Item> {
self.items.iter().filter(...).collect()
}
```
This causes us problems as we're returning owned Item's and Item is a
large nested structure that would be expensive to clone.
Our current work around was to put Item into an Arc, as Arc is
comparatively cheap to clone. So our method becomes:
```
async fn items(&self, ...) -> Vec<Arc<Item>> {
self.items.iter().filter(...).map(Arc::clone).collect()
}
```
However to support this we needed Arc to implement GraphQLTypeAsync.
This commit adds that support to juniper, by forwarding to the
GraphQLTypeAsync implementation for the contained type.
It's possible that we could have acheived something similar by adding
some lifetimes to our resolver and returning a reference, but using an
Arc was easier for us in this case. I'm not sure if there's any reason
why this would be a bad addition to Juniper overall?
* Move GraphQLTypeAsync for Arc<T> into pointers.rs
* Validate variables of the executed operation only
* Use `unreachable!` in `validate_var_defs`.
Use `unreachable!` instead of `panic!` on invalid variable types,
since thay have already been checked during document validation.
* Fix formatting in `validation/input_value.rs`
The `uuid` maintainers have started releasing in the `0.8` version train. I've relaxed the version requirements on `juniper`'s dependencies to allow juniper users to specify a different version in their `Cargo.toml` and still have the integration work.
The trait was introduced while introducing generic scalars, but is not
actually required or useful. It's functionality is fully covered by
methods on the `ScalarValue` trait.
It also forced a lof of for<'a> ScalarRefValue bounds all over the code,
complicating signatures a lot.
It is completely removed now.
* feat: Raw identifier support in object macro
This commit implements raw identifier (`r#name`) support
for field names (methods) and arguments in the `object` proc macro.
Eg:
```rust
impl T {
fn r#type(r#trait: String) -> bool {}
}
```
* Rebase onto master
* Fix merge [skip ci]
This commit implements raw identifier (`r#name`) support
for field names (methods) and arguments in the `object` proc macro.
Eg:
```rust
impl T {
fn r#type(r#trait: String) -> bool {}
}
```
style: Enable rustfmt merge_imports and format
This commit enables the rustfmt merge_imports setting
and formats the whole code base accordingly.
Note that the setting is not stable yet, but will be with Rust 1.38.
In the meantime, running fmt on stable will just leave the
changes alone so no problems should occur.
style: Enable rustfmt merge_imports and format
This commit enables the rustfmt merge_imports setting
and formats the whole code base accordingly.
Note that the setting is not stable yet, but will be with Rust 1.38.
In the meantime, running fmt on stable will just leave the
changes alone so no problems should occur.
style: Enable rustfmt merge_imports and format
This commit enables the rustfmt merge_imports setting
and formats the whole code base accordingly.
Note that the setting is not stable yet, but will be with Rust 1.38.
In the meantime, running fmt on stable will just leave the
changes alone so no problems should occur.
This commit implements a newtype style custom derive
for scalars via `#[derive(GraphQLScalarValue)]`, which now
supports both deriving a base enum scalar type and newtypes.
For newtypes, the `#[graphql(transparent)]` attribute is
required.
This commit:
* implements the derive
* adds integration tests
* updates the book
This impl can cause weird runtime errors and serves
no real practical purpose.
Removing the impl is a breaking change but is the only
way to error out at runtime.
Measuring the runtime of queries will only tell if there are slow
queries. To find out which queries are slow you need the operation name.
Getting the operation name was previously not possible from a Rocket
request handler. This fixes that.
This commit deprecates the graphql_object macro and replaces
all of it's uses with the new impl_object proc macro.
(Except for the old macro tests).
This commit also adds new integration tests for impl_object.
With the new HashMap implementation, the maps on stable and nightly
have different ordering.
The introspection tests were relying on strict ordering.
This commit adds a simple sorting of the results to prevent
test failures.
The literal value according to the standard is INLINE_FRAGMENT,
not INLINE_SPREAD.
This oversight leads to invalid introspection schemas and trips up
third party tools.
Currently, custom derives inside the main juniper crate are supported by
an ugly hack using the __juniper_use_everything macro.
This commit adds new custom derive variants that are for
main juniper crate internal use only (GraphQL{Enum,InputObject}Internal.
All custom derives inside the juniper crate are refactored to use the
new '*Internal' derives.
This allows us to
* remove the use_everything macro,
* simplify the generated code for custom derives
* support the Rust 2018 edition
This commit refactors the macros to use the $crate::inner_macro
trick instead of local_inner_macros.
This is possible since we only support rust 1.30 as a minimum version.
(the $crate:: method only works on 1.30+).
With this change, the wrapper helper macros for std macros can also
be removed.
Partially fixes https://github.com/graphql-rust/juniper/issues/248.
* Install `cargo-release`. (currently need a patched one with https://github.com/sunng87/cargo-release/pull/74)
* Run `cargo make release-dry-run` to do a dry run of a release
* Run `cargo make release` to do a minor versioned release of every crate
* Run `cargo make release-patch` to do a patch release of every crate
To only release one crate:
* Change directories into the desired crate
* Point `cargo-make` to the workspace-level Makefile when running a command. For example, `cargo make --makefile ../Makefile.toml release-dry-run`.
From the workspace root, run `cargo
* Update object/iface macro with doc/deprecated attrs for fields
* Use the note from `#[deprecated]` by default in derived GraphQLType
* Update to support multiline raw-docstring format
* Support bare deprecated attribute
* Update arguments to support #[doc] for parity with previous ` as ` syntax
Introduce an abstraction for scalar values
Before this change, possible scalar values were hard coded to be representable
by one of the following types: `i32`, `f64`, `String` or `bool`. This
restricts the types of custom scalar values that can be defined. For
example, it was not possible to define a scalar value that represents an
`i64` without mapping it to a string (which would be inefficient).
One solution to fix the example above would simply be to change the
internal representation to allow it to represent an `i64`, but this would
only fix the problem for one type (until someone wants to support
`i128` for example). Also this would make juniper not follow the
GraphQL standard closely.
This commit takes another approach, by making the exact "internal"
representation of scalar values swappable (in such a way that a downstream crate could provide its own representation tailored to their needs). This allows juniper to provide a default type that only
contains the types described in the standard whereas other crates could define custom scalars for their needs.
To accomplish this we need to change several things in the current implementation:
* Add some traits that abstract the behavior of such a scalar value representation
* Change `Value` and `InputValue` to have a scalar variant (with a
generic type) instead of hard coded variants for the standard
types. This implies adding a generic parameter to both enums that
needs to be added in the whole crate.
* Change the parser to allow deciding between different types of
scalar values. The problem is basically that the original parser
implementation had no way to know whether a parsed integer number is
a `i32` or a `i64` (for example). To fix this we added some knowledge
of the existing schema to the parser.
* Fix some macros and derives to follow the new behavior.
This commit also contains an unrelated change about the way `juniper_codegen`
resolves items from `juniper`. The `_internal` flag is removed and
the resolution is replaced by a macro.
The scalar parsing strategy is as follows:
* Pass optional type information all the way down in the parser. If a
field/type/… does note exist, just do not pass down the type
information.
* The lexer now distinguishes between several fundamental scalar types (`String`, `Float`, `Int`). It does not try to actually parse those values, instead it just annotates them that this is a floating point number, an integer number, or a string value, etc.
* If type information exists while parsing a scalar value, try the following:
1. Try parsing the value using that type information.
2. If that fails try parsing the value using the inferred type information from the lexer.
* If no type information exists, try parsing the scalar value using the inferred type from the lexer,
All macros support the introduced scalar value abstraction. It is now possible to specify if a certain implementation should be based on a specific scalar value representation or be generic about the exact representation. All macros now default to the `DefaultScalarValue` type provided by
`juniper` if no scalar value representation is specified. This is done with usability and backwards compatibility in mind.
Finally, we allow specifying the scalar value representations via an attribute
(`#[graphql(scalar = "Type")]`). A default generic implementation
is provided.
* Bump` juniper`, `juniper_codegen`, and `juniper_tests` versions.
* Bump integration crate requirements to include 0.10.0. `juniper_iron` gets a semver breaking version as it has a breaking change but `juniper_iron` does not.
* Move `juniper_rocket` changelog into one file. This aligns with `juniper_iron` and will be easier
to automate in the future.
* Let `juniper_warp` and `juniper_hyper` use `0.9.x` versions of Juniper. They don't rely on anything in 0.10.0 so don't require it.
This enables Rust2018-style macro imports:
```rust
use juniper::graphql_object;
graphql_object!(User: () |&self| { ... });
```
In the future when dropping compatibility with pre-2018 compilers,
this can be replaced with the explicit `$crate` prefixes instead of
`local_inner_macros`.
In `macro_rules!` with the annotation `local_inner_macros`, all of macro calls
are transformed into `$crate::builtin!(...)` (See [1] for details).
Therefore, name resolutions of built-in macros are not perfomed correctly.
To avoid this, some helper macros are introduced to make built-in
macros be interpreted as crate-local macros.
[1]: https://github.com/rust-lang/rust/issues/53464#issuecomment-414049821
Performance improvements
* Replace the IndexMap in the serialized object with a plain
`Vec<(String, Value)>` because linear search is faster for few
elements
* Some general tweaks to skip some allocations
* Added trait to convert a custom error type into a FieldError
* Convert the error type of the gql fields if it implements IntoFieldError
* Added test case to check if custom error handling works
* Added to changelog
GraphQL spec requires every error contain `{"message": "field"}`. Every
error in juniper except ones fixed here are reported consistently with
this style. This commit fixes ones left.
The conversions in this changeset cannot use the `From<T>` trait
implementation because the conversion is lossy, either because they
involve converting a signed value to an unsigned value (`i32`⇒`u64`)
or because the convert from a larger data type to a smaller one
(`u64`⇒`i32`). In this case, the `as` type cast is necessary to perform
a bitwise conversion.
This coercion can cause negative values to become very large unsigned
values. This is intentional on line 90.
It doesn't appear that `:tt` accepts the `stringify!()`-ed value in this
position. The :tt is only later used as an `:expr` to produce the name
for metadata purposes.
Converting this position to be an `:expr` allows the `stringify!()`-ed
value and accepts all current uses of the `graphql_scalar!()` macro in
this repository.
Fix chrono DateTime support
The DateTime support was improperly implemented with time (hour + minute support), which is fixed by this commit.
Documentation and tests have also been updated.
Only author: @sporto
Without this change tests were failing to compile:
```
---- src/value.rs - graphql_value (line 196) stdout ----
error[E0468]: an `extern crate` loading macros must be at the crate root
--> src/value.rs:197:14
|
3 | #[macro_use] extern crate juniper;
| ^^^^^^^^^^^^^^^^^^^^^
thread 'rustc' panicked at 'couldn't compile the test', librustdoc/test.rs:295:13
note: Run with `RUST_BACKTRACE=1` for a backtrace.
```
I also confirmed that `main` does not show up in the docs with
this change.
* Extend derive for enums to allow deriving inside the juniper crate
itself. Note: this is a rather ugly hack right now, FIXME is in the
code
* Remove the graphql_enum! macro and replace all internal use with
derive
* Refactor introspection tests to use derive
This is not 100% accurate - it will be set to the literal type of what
a field returns, so it might be wrapped in non-null/list when it
technically shouldn't.
For this use-case it's fine, but if we want to (officially) add it to
the public API surface, we should probably make it accurate.
This is just a useful thing for me because I need to clone the http request.
This shouldn't really influence anything else, every field already implements `Clone`