Skip to content
Merged
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
705 changes: 55 additions & 650 deletions src/main/java/graphql/Scalars.java

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions src/main/java/graphql/scalar/CoercingUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package graphql.scalar;

import graphql.Internal;

@Internal
class CoercingUtil {
static boolean isNumberIsh(Object input) {
return input instanceof Number || input instanceof String;
}

static String typeName(Object input) {
if (input == null) {
return "null";
}

return input.getClass().getSimpleName();
}
}
73 changes: 73 additions & 0 deletions src/main/java/graphql/scalar/GraphqlBigDecimalCoercing.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package graphql.scalar;

import graphql.Internal;
import graphql.language.FloatValue;
import graphql.language.IntValue;
import graphql.language.StringValue;
import graphql.schema.Coercing;
import graphql.schema.CoercingParseLiteralException;
import graphql.schema.CoercingParseValueException;
import graphql.schema.CoercingSerializeException;

import java.math.BigDecimal;

import static graphql.scalar.CoercingUtil.isNumberIsh;
import static graphql.scalar.CoercingUtil.typeName;

@Internal
public class GraphqlBigDecimalCoercing implements Coercing<BigDecimal, BigDecimal> {

private BigDecimal convertImpl(Object input) {
if (isNumberIsh(input)) {
try {
return new BigDecimal(input.toString());
} catch (NumberFormatException e) {
return null;
}
}
return null;

}

@Override
public BigDecimal serialize(Object input) {
BigDecimal result = convertImpl(input);
if (result == null) {
throw new CoercingSerializeException(
"Expected type 'BigDecimal' but was '" + typeName(input) + "'."
);
}
return result;
}

@Override
public BigDecimal parseValue(Object input) {
BigDecimal result = convertImpl(input);
if (result == null) {
throw new CoercingParseValueException(
"Expected type 'BigDecimal' but was '" + typeName(input) + "'."
);
}
return result;
}

@Override
public BigDecimal parseLiteral(Object input) {
if (input instanceof StringValue) {
try {
return new BigDecimal(((StringValue) input).getValue());
} catch (NumberFormatException e) {
throw new CoercingParseLiteralException(
"Unable to turn AST input into a 'BigDecimal' : '" + input + "'"
);
}
} else if (input instanceof IntValue) {
return new BigDecimal(((IntValue) input).getValue());
} else if (input instanceof FloatValue) {
return ((FloatValue) input).getValue();
}
throw new CoercingParseLiteralException(
"Expected AST type 'IntValue', 'StringValue' or 'FloatValue' but was '" + typeName(input) + "'."
);
}
}
86 changes: 86 additions & 0 deletions src/main/java/graphql/scalar/GraphqlBigIntegerCoercing.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package graphql.scalar;

import graphql.Internal;
import graphql.language.FloatValue;
import graphql.language.IntValue;
import graphql.language.StringValue;
import graphql.schema.Coercing;
import graphql.schema.CoercingParseLiteralException;
import graphql.schema.CoercingParseValueException;
import graphql.schema.CoercingSerializeException;

import java.math.BigDecimal;
import java.math.BigInteger;

import static graphql.scalar.CoercingUtil.isNumberIsh;
import static graphql.scalar.CoercingUtil.typeName;

@Internal
public class GraphqlBigIntegerCoercing implements Coercing<BigInteger, BigInteger> {

private BigInteger convertImpl(Object input) {
if (isNumberIsh(input)) {
BigDecimal value;
try {
value = new BigDecimal(input.toString());
} catch (NumberFormatException e) {
return null;
}
try {
return value.toBigIntegerExact();
} catch (ArithmeticException e) {
return null;
}
}
return null;

}

@Override
public BigInteger serialize(Object input) {
BigInteger result = convertImpl(input);
if (result == null) {
throw new CoercingSerializeException(
"Expected type 'BigInteger' but was '" + typeName(input) + "'."
);
}
return result;
}

@Override
public BigInteger parseValue(Object input) {
BigInteger result = convertImpl(input);
if (result == null) {
throw new CoercingParseValueException(
"Expected type 'BigInteger' but was '" + typeName(input) + "'."
);
}
return result;
}

@Override
public BigInteger parseLiteral(Object input) {
if (input instanceof StringValue) {
try {
return new BigDecimal(((StringValue) input).getValue()).toBigIntegerExact();
} catch (NumberFormatException | ArithmeticException e) {
throw new CoercingParseLiteralException(
"Unable to turn AST input into a 'BigInteger' : '" + input + "'"
);
}
} else if (input instanceof IntValue) {
return ((IntValue) input).getValue();
} else if (input instanceof FloatValue) {
try {
return ((FloatValue) input).getValue().toBigIntegerExact();
} catch (ArithmeticException e) {
throw new CoercingParseLiteralException(
"Unable to turn AST input into a 'BigInteger' : '" + input + "'"
);
}
}
throw new CoercingParseLiteralException(
"Expected AST type 'IntValue', 'StringValue' or 'FloatValue' but was '" + typeName(input) + "'."
);
}
}
70 changes: 70 additions & 0 deletions src/main/java/graphql/scalar/GraphqlBooleanCoercing.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package graphql.scalar;

import graphql.Internal;
import graphql.language.BooleanValue;
import graphql.schema.Coercing;
import graphql.schema.CoercingParseLiteralException;
import graphql.schema.CoercingParseValueException;
import graphql.schema.CoercingSerializeException;

import java.math.BigDecimal;

import static graphql.Assert.assertShouldNeverHappen;
import static graphql.scalar.CoercingUtil.isNumberIsh;
import static graphql.scalar.CoercingUtil.typeName;

@Internal
public class GraphqlBooleanCoercing implements Coercing<Boolean, Boolean> {

private Boolean convertImpl(Object input) {
if (input instanceof Boolean) {
return (Boolean) input;
} else if (input instanceof String) {
return Boolean.parseBoolean((String) input);
} else if (isNumberIsh(input)) {
BigDecimal value;
try {
value = new BigDecimal(input.toString());
} catch (NumberFormatException e) {
// this should never happen because String is handled above
return assertShouldNeverHappen();
}
return value.compareTo(BigDecimal.ZERO) != 0;
} else {
return null;
}

}

@Override
public Boolean serialize(Object input) {
Boolean result = convertImpl(input);
if (result == null) {
throw new CoercingSerializeException(
"Expected type 'Boolean' but was '" + typeName(input) + "'."
);
}
return result;
}

@Override
public Boolean parseValue(Object input) {
Boolean result = convertImpl(input);
if (result == null) {
throw new CoercingParseValueException(
"Expected type 'Boolean' but was '" + typeName(input) + "'."
);
}
return result;
}

@Override
public Boolean parseLiteral(Object input) {
if (!(input instanceof BooleanValue)) {
throw new CoercingParseLiteralException(
"Expected AST type 'BooleanValue' but was '" + typeName(input) + "'."
);
}
return ((BooleanValue) input).isValue();
}
}
80 changes: 80 additions & 0 deletions src/main/java/graphql/scalar/GraphqlByteCoercing.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package graphql.scalar;

import graphql.Internal;
import graphql.language.IntValue;
import graphql.schema.Coercing;
import graphql.schema.CoercingParseLiteralException;
import graphql.schema.CoercingParseValueException;
import graphql.schema.CoercingSerializeException;

import java.math.BigDecimal;
import java.math.BigInteger;

import static graphql.scalar.CoercingUtil.isNumberIsh;
import static graphql.scalar.CoercingUtil.typeName;

@Internal
public class GraphqlByteCoercing implements Coercing<Byte, Byte> {

private static final BigInteger BYTE_MAX = BigInteger.valueOf(Byte.MAX_VALUE);
private static final BigInteger BYTE_MIN = BigInteger.valueOf(Byte.MIN_VALUE);

private Byte convertImpl(Object input) {
if (input instanceof Byte) {
return (Byte) input;
} else if (isNumberIsh(input)) {
BigDecimal value;
try {
value = new BigDecimal(input.toString());
} catch (NumberFormatException e) {
return null;
}
try {
return value.byteValueExact();
} catch (ArithmeticException e) {
return null;
}
} else {
return null;
}

}

@Override
public Byte serialize(Object input) {
Byte result = convertImpl(input);
if (result == null) {
throw new CoercingSerializeException(
"Expected type 'Byte' but was '" + typeName(input) + "'."
);
}
return result;
}

@Override
public Byte parseValue(Object input) {
Byte result = convertImpl(input);
if (result == null) {
throw new CoercingParseValueException(
"Expected type 'Byte' but was '" + typeName(input) + "'."
);
}
return result;
}

@Override
public Byte parseLiteral(Object input) {
if (!(input instanceof IntValue)) {
throw new CoercingParseLiteralException(
"Expected AST type 'IntValue' but was '" + typeName(input) + "'."
);
}
BigInteger value = ((IntValue) input).getValue();
if (value.compareTo(BYTE_MIN) < 0 || value.compareTo(BYTE_MAX) > 0) {
throw new CoercingParseLiteralException(
"Expected value to be in the Byte range but it was '" + value.toString() + "'"
);
}
return value.byteValue();
}
}
63 changes: 63 additions & 0 deletions src/main/java/graphql/scalar/GraphqlCharCoercing.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package graphql.scalar;

import graphql.Internal;
import graphql.language.StringValue;
import graphql.schema.Coercing;
import graphql.schema.CoercingParseLiteralException;
import graphql.schema.CoercingParseValueException;
import graphql.schema.CoercingSerializeException;

import static graphql.scalar.CoercingUtil.typeName;

@Internal
public class GraphqlCharCoercing implements Coercing<Character, Character> {

private Character convertImpl(Object input) {
if (input instanceof String && ((String) input).length() == 1) {
return ((String) input).charAt(0);
} else if (input instanceof Character) {
return (Character) input;
} else {
return null;
}

}

@Override
public Character serialize(Object input) {
Character result = convertImpl(input);
if (result == null) {
throw new CoercingSerializeException(
"Expected type 'Char' but was '" + typeName(input) + "'."
);
}
return result;
}

@Override
public Character parseValue(Object input) {
Character result = convertImpl(input);
if (result == null) {
throw new CoercingParseValueException(
"Expected type 'Char' but was '" + typeName(input) + "'."
);
}
return result;
}

@Override
public Character parseLiteral(Object input) {
if (!(input instanceof StringValue)) {
throw new CoercingParseLiteralException(
"Expected AST type 'StringValue' but was '" + typeName(input) + "'."
);
}
String value = ((StringValue) input).getValue();
if (value.length() != 1) {
throw new CoercingParseLiteralException(
"Empty 'StringValue' provided."
);
}
return value.charAt(0);
}
}
Loading