Created
July 16, 2020 23:25
-
-
Save erikdstock/09dc318dfea84f5f4f307fc2a487aecd to your computer and use it in GitHub Desktop.
Example method of organizing sangria type
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package graphql.models | |
import java.text.DecimalFormat | |
import sangria.validation.ValueCoercionViolation | |
import json.SprayJsonConversions | |
import sangria.macros.derive.{ | |
deriveObjectType, AddFields, ObjectTypeDescription, ObjectTypeName | |
} | |
import sangria.schema.{ | |
Argument, BooleanType, Field, IntType, LongType, OptionInputType, ScalarAlias, | |
StringType | |
} | |
import sangria.marshalling.sprayJson._ | |
case class Money(units: Long) { | |
def displayAmount( | |
fractionalDigits: Int, | |
groupingSeparator: Char, | |
decimalSeparator: Char, | |
showFractionalAmount: Boolean | |
): String = { | |
require(units >= 0 && units < Math.pow(2, 53), MoneyUnitCoercionViolation) | |
val formatter = new DecimalFormat() | |
val symbols = formatter.getDecimalFormatSymbols | |
symbols.setGroupingSeparator(groupingSeparator) | |
symbols.setDecimalSeparator(decimalSeparator) | |
formatter.setDecimalFormatSymbols(symbols) | |
formatter.setMinimumFractionDigits( | |
if (showFractionalAmount) fractionalDigits else 0 | |
) | |
formatter.setMaximumFractionDigits(fractionalDigits) | |
val displayAmount = units / scala.math.pow(10, fractionalDigits) | |
formatter.format( | |
if (showFractionalAmount) displayAmount else Math.ceil(displayAmount) | |
) | |
} | |
} | |
object Money extends SprayJsonConversions { | |
case object MoneyUnitCoercionViolation | |
extends ValueCoercionViolation("Number exceeds 2^53 ") | |
val MoneyUnitType = ScalarAlias[Long, Long]( | |
LongType, | |
identity, | |
(l: Long) => | |
if (l >= 0 && l < Math.pow(2, 53)) Right(l) | |
else Left(MoneyUnitCoercionViolation) | |
) | |
val fractionalDigits = Argument.createWithDefault( | |
"fractionalDigits", | |
OptionInputType(IntType), | |
Some("Number of decimal places for the currency."), | |
2 | |
) | |
val groupingSeparator = | |
Argument.createWithDefault( | |
"groupingSeparator", | |
OptionInputType(CharType), | |
Some("The 1000s separator."), | |
',' | |
) | |
val decimalSeparator = | |
Argument.createWithDefault( | |
"decimalSeparator", | |
OptionInputType(CharType), | |
Some("The decimal separator."), | |
'.' | |
) | |
val showFractionalAmount = Argument.createWithDefault( | |
"showFractionalDigits", | |
OptionInputType(BooleanType), | |
Some("Whether to show the fractional units."), | |
true | |
) | |
lazy val MoneyType = deriveObjectType[Unit, Money]( | |
ObjectTypeName("Money"), | |
ObjectTypeDescription("Represents currency units and formatting"), | |
AddFields( | |
Field( | |
"displayAmount", | |
StringType, | |
description = Some("Formatted string version of currency amount"), | |
arguments = List( | |
fractionalDigits, | |
groupingSeparator, | |
decimalSeparator, | |
showFractionalAmount | |
), | |
resolve = c => | |
c.value.displayAmount( | |
c.arg(fractionalDigits), | |
c.arg(groupingSeparator), | |
c.arg(decimalSeparator), | |
c.arg(showFractionalAmount) | |
) | |
) | |
) | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment