2018-01-13 03:34:30 -06:00
|
|
|
# [master] yyyy-mm-dd
|
2018-01-11 19:23:49 -06:00
|
|
|
|
|
|
|
## Changes
|
Introduce an abstraction for scalar values (#251)
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.
2018-10-22 22:40:14 -05:00
|
|
|
|
2018-12-03 19:28:49 -06:00
|
|
|
- The minimum required Rust version is now `1.28.0`.
|
|
|
|
|
|
|
|
[#271](https://github.com/graphql-rust/juniper/pull/271)
|
|
|
|
|
Introduce an abstraction for scalar values (#251)
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.
2018-10-22 22:40:14 -05:00
|
|
|
- Juniper is now generic about the exact representation of scalar values. This
|
|
|
|
allows downstream crates to add support for own scalar value representations.
|
|
|
|
|
|
|
|
There are two use cases for this feature:
|
|
|
|
* You want to support new scalar types not representable by the provided default
|
|
|
|
scalar value representation like for example `i64`
|
|
|
|
* You want to support a type from a third party crate that is not supported by juniper
|
|
|
|
|
|
|
|
**Note:** This may need some changes in down stream code, especially if working with
|
|
|
|
generic code. To retain the current behaviour use `DefaultScalarValue` as scalar value type
|
|
|
|
|
|
|
|
[#251](https://github.com/graphql-rust/juniper/pull/251)
|
2018-10-27 22:28:48 -05:00
|
|
|
|
|
|
|
- The `GraphQLObject` and `GraphQLEnum` derives will mark graphql fields as
|
|
|
|
`@deprecated` when struct fields or enum variants are marked with the
|
|
|
|
builtin `#[deprecated]` attribute.
|
|
|
|
|
|
|
|
The deprecation reason can be set using the `note = ...` meta item
|
|
|
|
(e.g. `#[deprecated(note = "Replaced by betterField")]`).
|
|
|
|
The `since` attribute is ignored.
|
|
|
|
|
|
|
|
[#269](https://github.com/graphql-rust/juniper/pull/269)
|
|
|
|
|
|
|
|
|
|
|
|
- There is an alternative syntax for setting a field's _description_ and
|
|
|
|
_deprecation reason_ in the `graphql_object!` and `graphql_interface!` macros.
|
|
|
|
|
|
|
|
To __deprecate__ a graphql field:
|
|
|
|
```rust
|
|
|
|
// Original syntax for setting deprecation reason
|
|
|
|
field deprecated "Reason" my_field() -> { ... }
|
|
|
|
|
|
|
|
// New alternative syntax for deprecation reason.
|
|
|
|
#[deprecated(note = "Reason")]
|
|
|
|
field my_field() -> { ... }
|
|
|
|
|
|
|
|
// You can now also deprecate without a reason.
|
|
|
|
#[deprecated]
|
|
|
|
field my_field() -> { ... }
|
|
|
|
```
|
|
|
|
|
|
|
|
To set the __description__ of a graphql field:
|
|
|
|
```rust
|
|
|
|
// Original syntax for field descriptions
|
|
|
|
field my_field() as "Description" -> { ... }
|
|
|
|
|
|
|
|
// Original syntax for argument descriptions
|
|
|
|
field my_field(
|
|
|
|
floops: i32 as "The number of starfish to be returned. \
|
|
|
|
Can't be more than 100.",
|
|
|
|
) -> {
|
|
|
|
...
|
|
|
|
}
|
|
|
|
|
|
|
|
// New alternative syntax for field descriptions
|
2018-11-11 16:58:50 -06:00
|
|
|
/// Description
|
2018-10-27 22:28:48 -05:00
|
|
|
field my_field() -> { ... }
|
|
|
|
|
|
|
|
// New alternative syntax for argument descriptions
|
|
|
|
field my_field(
|
2018-11-11 16:58:50 -06:00
|
|
|
/// The number of starfish to be returned.
|
|
|
|
/// Can't be more than 100.
|
2018-10-27 22:28:48 -05:00
|
|
|
arg: i32,
|
|
|
|
) -> {
|
|
|
|
...
|
|
|
|
}
|
|
|
|
|
|
|
|
// You can also use raw strings and const &'static str.
|
|
|
|
//
|
|
|
|
// Multiple docstrings will be collapsed into a single
|
|
|
|
// description separated by newlines.
|
2018-11-11 16:58:50 -06:00
|
|
|
/// This is my field.
|
|
|
|
///
|
|
|
|
/// Make sure not to filtz the bitlet.
|
|
|
|
/// Flitzing without a bitlet has undefined behaviour.
|
|
|
|
///
|
2018-10-27 22:28:48 -05:00
|
|
|
#[doc = my_consts::ADDED_IN_VERSION_XYZ]
|
|
|
|
field my_field() -> { ... }
|
|
|
|
```
|
|
|
|
|
|
|
|
[#269](https://github.com/graphql-rust/juniper/pull/269)
|