-
Notifications
You must be signed in to change notification settings - Fork 433
Redesign GraphQLScalar
macros
#1017
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
Conversation
GraphQLScalar
macroGraphQLScalar
and graphql_scalar
macros
GraphQLScalar
and graphql_scalar
macrosGraphQLScalar
and graphql_scalar
macros
FCM
|
@tyranron at the end I've decided not to split PRs for derive and attribute macros, because built-in scalar implementation are looking better with both macros present: #[derive(Clone, Debug, Eq, GraphQLScalar, PartialEq, Serialize, Deserialize)]
#[graphql(with = id, parse_token(String, i32))]
pub struct ID(String);
mod id {
use super::*;
pub(super) type Error = String;
pub(super) fn to_output<S: ScalarValue>(v: &ID) -> Value<S> {
Value::scalar(v.0.clone())
}
pub(super) fn from_input<S: ScalarValue>(v: &InputValue<S>) -> Result<ID, Error> {
v.as_string_value()
.map(str::to_owned)
.or_else(|| v.as_int_value().map(|i| i.to_string()))
.map(ID)
.ok_or_else(|| format!("Expected `String` or `Int`, found: {}", v))
}
}
#[graphql_scalar(with = int)]
type Int = i32;
mod int {
use super::*;
pub(super) type Error = String;
pub(super) fn to_output<S: ScalarValue>(v: &Int) -> Value<S> {
Value::scalar(*v)
}
pub(super) fn from_input<S: ScalarValue>(v: &InputValue<S>) -> Result<Int, Error> {
v.as_int_value()
.ok_or_else(|| format!("Expected `Int`, found: {}", v))
}
pub(super) fn parse_token<S: ScalarValue>(value: ScalarToken<'_>) -> ParseScalarResult<'_, S> {
if let ScalarToken::Int(v) = value {
v.parse()
.map_err(|_| ParseError::UnexpectedToken(Token::Scalar(value)))
.map(|s: i32| s.into())
} else {
Err(ParseError::UnexpectedToken(Token::Scalar(value)))
}
}
} |
GraphQLScalar
and graphql_scalar
macrosGraphQLScalar
macros
# Conflicts: # docs/book/content/types/scalars.md # integration_tests/juniper_tests/src/codegen/mod.rs # integration_tests/juniper_tests/src/codegen/scalar_attr_derive_input.rs # juniper/src/executor_tests/introspection/mod.rs # juniper/src/executor_tests/variables.rs # juniper/src/lib.rs # juniper/src/types/scalars.rs # juniper_codegen/src/graphql_scalar/attr.rs # juniper_codegen/src/graphql_scalar/mod.rs # juniper_codegen/src/lib.rs # juniper_codegen/src/result.rs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ilslv great work, thanks! 🍻
let attr = Attr::from_attrs("graphql", &ast.attrs)?; | ||
|
||
let field = match ( | ||
attr.to_output.as_deref().cloned(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This whole match
is quite a repeatable pattern. It'd better be deduced into a separate method.
@rimutaka the current Book isn't ideal, but should be up-to-date with these changes on the current |
Part of #1010
Synopsis
Main goal of this PR is to support generic scalars.
Solution
In addition to this PR tries to unify
#[graphql_scalar]
and#[derive(GraphQLScalar)]
macros. This is done by introducing ability to use custom resolvers:But we can't remove
#[graphql_scalar]
macro entirely because of uncovered use-case of derive macro: types from other crateChecklist
Draft:
prefixDraft:
prefix is removed