Skip to content

Commit 17e7881

Browse files
authored
Merge pull request #83 from abelmosch/add-scalars
Added CountryCodeScalar & CurrencyScalar
2 parents c44b3b2 + 8b63d94 commit 17e7881

File tree

8 files changed

+867
-2
lines changed

8 files changed

+867
-2
lines changed

README.md

+50
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,56 @@ An example query to look for customers in the Romanian locale might look like:
274274
}
275275

276276
```
277+
## Country Code Scalar
278+
The CountryCode scalar type as defined by [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2).
279+
280+
281+
An example declaration in SDL might be:
282+
```graphql
283+
scalar CountryCode
284+
285+
type Customer {
286+
name : String
287+
countryCode : CountryCode
288+
}
289+
```
290+
291+
And example query might look like:
292+
293+
```graphql
294+
query {
295+
customers(code : "US") {
296+
name
297+
countryCode
298+
}
299+
}
300+
```
301+
## Currency Scalar
302+
303+
A field whose value is an [ISO-4217](https://en.wikipedia.org/wiki/ISO_4217) currency.
304+
305+
An example declaration in SDL might be:
306+
```graphql
307+
scalar Currency
308+
309+
type Account {
310+
id : String
311+
currency : Currency
312+
accountNumber: String
313+
}
314+
```
315+
316+
And example query might look like:
317+
318+
```graphql
319+
query {
320+
accounts(currency : "USD") {
321+
id
322+
currency
323+
accountNumber
324+
}
325+
}
326+
```
277327

278328
## Alias Scalars
279329

src/main/java/graphql/scalars/ExtendedScalars.java

+14-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import graphql.PublicApi;
44
import graphql.scalars.alias.AliasedScalar;
5+
import graphql.scalars.country.code.CountryCodeScalar;
6+
import graphql.scalars.currency.CurrencyScalar;
57
import graphql.scalars.datetime.DateScalar;
68
import graphql.scalars.datetime.DateTimeScalar;
79
import graphql.scalars.datetime.LocalTimeCoercing;
@@ -23,8 +25,6 @@
2325
import graphql.scalars.url.UrlScalar;
2426
import graphql.schema.GraphQLScalarType;
2527

26-
import java.util.UUID;
27-
2828
/**
2929
* This is the API entry point for all the extended scalars
3030
*/
@@ -138,6 +138,18 @@ public class ExtendedScalars {
138138
*/
139139
public static final GraphQLScalarType Locale = LocaleScalar.INSTANCE;
140140

141+
/**
142+
* A field whose value is an ISO-4217 currency.
143+
* See the <a href="https://en.wikipedia.org/wiki/ISO_4217">ISO-4217</a> for more details.
144+
*/
145+
public static final GraphQLScalarType Currency = CurrencyScalar.INSTANCE;
146+
147+
/**
148+
* The CountryCode scalar type as defined by ISO 3166-1 alpha-2.
149+
* See the <a href="https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2">ISO 3166-1 alpha-2</a> for more details.
150+
*/
151+
public static final GraphQLScalarType CountryCode = CountryCodeScalar.INSTANCE;
152+
141153
/**
142154
* A UUID scalar that accepts a universally unique identifier and produces {@link
143155
* java.util.UUID} objects at runtime.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package graphql.scalars.country.code;
2+
3+
/**
4+
* The CountryCode list as defined by ISO 3166-1 alpha-2.
5+
* See the <a href="https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2">ISO 3166-1 alpha-2</a> for more details.
6+
*/
7+
public enum CountryCode {
8+
AD, AE, AF, AG, AI, AL, AM, AO, AQ, AR, AS, AT, AU, AW, AX, AZ, BA, BB, BD, BE, BF, BG, BH, BI, BJ, BL, BM, BN, BO,
9+
BQ, BR, BS, BT, BV, BW, BY, BZ, CA, CC, CD, CF, CG, CH, CI, CK, CL, CM, CN, CO, CR, CU, CV, CW, CX, CY, CZ, DE, DJ,
10+
DK, DM, DO, DZ, EC, EE, EG, EH, ER, ES, ET, FI, FJ, FK, FM, FO, FR, GA, GB, GD, GE, GF, GG, GH, GI, GL, GM, GN, GP,
11+
GQ, GR, GS, GT, GU, GW, GY, HK, HM, HN, HR, HT, HU, ID, IE, IL, IM, IN, IO, IQ, IR, IS, IT, JE, JM, JO, JP, KE, KG,
12+
KH, KI, KM, KN, KP, KR, KW, KY, KZ, LA, LB, LC, LI, LK, LR, LS, LT, LU, LV, LY, MA, MC, MD, ME, MF, MG, MH, MK, ML,
13+
MM, MN, MO, MP, MQ, MR, MS, MT, MU, MV, MW, MX, MY, MZ, NA, NC, NE, NF, NG, NI, NL, NO, NP, NR, NU, NZ, OM, PA, PE,
14+
PF, PG, PH, PK, PL, PM, PN, PR, PS, PT, PW, PY, QA, RE, RO, RS, RU, RW, SA, SB, SC, SD, SE, SG, SH, SI, SJ, SK, SL,
15+
SM, SN, SO, SR, SS, ST, SV, SX, SY, SZ, TC, TD, TF, TG, TH, TJ, TK, TL, TM, TN, TO, TR, TT, TV, TW, TZ, UA, UG, UM,
16+
US, UY, UZ, VA, VC, VE, VG, VI, VN, VU, WF, WS, YE, YT, ZA, ZM, ZW
17+
}
18+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package graphql.scalars.country.code;
2+
3+
import graphql.Internal;
4+
import graphql.language.StringValue;
5+
import graphql.language.Value;
6+
import graphql.schema.*;
7+
8+
import java.util.function.Function;
9+
10+
import static graphql.scalars.util.Kit.typeName;
11+
12+
/**
13+
* Access this via {@link graphql.scalars.ExtendedScalars#CountryCode}
14+
*/
15+
@Internal
16+
public class CountryCodeScalar {
17+
18+
public static final GraphQLScalarType INSTANCE;
19+
20+
static {
21+
Coercing<CountryCode, String> coercing = new Coercing<CountryCode, String>() {
22+
23+
@Override
24+
public String serialize(Object input) throws CoercingSerializeException {
25+
CountryCode countryCode = parseCountryCode(input, CoercingParseValueException::new);
26+
return countryCode.name();
27+
}
28+
29+
@Override
30+
public CountryCode parseValue(Object input) throws CoercingParseValueException {
31+
return parseCountryCode(input, CoercingParseValueException::new);
32+
}
33+
34+
@Override
35+
public CountryCode parseLiteral(Object input) throws CoercingParseLiteralException {
36+
if (!(input instanceof StringValue)) {
37+
throw new CoercingParseLiteralException("Expected AST type 'StringValue' but was '" + typeName(input) + "'.");
38+
}
39+
String stringValue = ((StringValue) input).getValue();
40+
return parseCountryCode(stringValue, CoercingParseLiteralException::new);
41+
42+
}
43+
44+
@Override
45+
public Value<?> valueToLiteral(Object input) {
46+
String s = serialize(input);
47+
return StringValue.newStringValue(s).build();
48+
}
49+
50+
private CountryCode parseCountryCode(Object input, Function<String, RuntimeException> exceptionMaker) {
51+
final CountryCode result;
52+
if (input instanceof String) {
53+
try {
54+
result = CountryCode.valueOf((String) input);
55+
} catch (NullPointerException | IllegalArgumentException ex) {
56+
throw exceptionMaker.apply("Invalid ISO 3166-1 alpha-2 value : '" + input + "'. because of : '" + ex.getMessage() + "'");
57+
}
58+
} else if (input instanceof CountryCode) {
59+
result = (CountryCode) input;
60+
} else {
61+
throw exceptionMaker.apply("Expected a 'String' or 'CountryCode' but was '" + typeName(input) + "'.");
62+
}
63+
return result;
64+
}
65+
};
66+
67+
INSTANCE = GraphQLScalarType.newScalar()
68+
.name("CountryCode")
69+
.description("The CountryCode scalar type as defined by ISO 3166-1 alpha-2.")
70+
.coercing(coercing).build();
71+
}
72+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package graphql.scalars.currency;
2+
3+
import graphql.Internal;
4+
import graphql.language.StringValue;
5+
import graphql.language.Value;
6+
import graphql.schema.*;
7+
8+
import java.util.Currency;
9+
import java.util.function.Function;
10+
11+
import static graphql.scalars.util.Kit.typeName;
12+
13+
/**
14+
* Access this via {@link graphql.scalars.ExtendedScalars#Currency}
15+
*/
16+
@Internal
17+
public class CurrencyScalar {
18+
19+
public static final GraphQLScalarType INSTANCE;
20+
21+
static {
22+
Coercing<Currency, String> coercing = new Coercing<Currency, String>() {
23+
@Override
24+
public String serialize(Object input) throws CoercingSerializeException {
25+
Currency currency = parseCurrency(input, CoercingSerializeException::new);
26+
return currency.getCurrencyCode();
27+
}
28+
29+
@Override
30+
public Currency parseValue(Object input) throws CoercingParseValueException {
31+
return parseCurrency(input, CoercingParseValueException::new);
32+
}
33+
34+
35+
@Override
36+
public Currency parseLiteral(Object input) throws CoercingParseLiteralException {
37+
if (!(input instanceof StringValue)) {
38+
throw new CoercingParseLiteralException("Expected AST type 'StringValue' but was '" + typeName(input) + "'.");
39+
}
40+
String stringValue = ((StringValue) input).getValue();
41+
return parseCurrency(stringValue, CoercingParseLiteralException::new);
42+
}
43+
44+
@Override
45+
public Value<?> valueToLiteral(Object input) {
46+
String serializedInput = serialize(input);
47+
return StringValue.newStringValue(serializedInput).build();
48+
}
49+
50+
51+
private Currency parseCurrency(Object input, Function<String, RuntimeException> exceptionMaker) {
52+
final Currency result;
53+
if (input instanceof Currency) {
54+
result = (Currency) input;
55+
} else if (input instanceof String) {
56+
try {
57+
result = Currency.getInstance((String) input);
58+
} catch (NullPointerException | IllegalArgumentException ex) {
59+
throw exceptionMaker.apply("Invalid ISO 4217 value : '" + input + "'. because of : '" + ex.getMessage() + "'");
60+
}
61+
} else {
62+
throw exceptionMaker.apply("Expected a 'String' or 'Currency' but was '" + typeName(input) + "'.");
63+
}
64+
return result;
65+
}
66+
};
67+
68+
INSTANCE = GraphQLScalarType.newScalar()
69+
.name("Currency")
70+
.description("An ISO-4217 compliant Currency Scalar")
71+
.coercing(coercing).build();
72+
}
73+
}

0 commit comments

Comments
 (0)