Skip to content

Commit

Permalink
Merge pull request #350 from fehu/transform-enum-names
Browse files Browse the repository at this point in the history
Transform enum values' names with a macro setting
  • Loading branch information
OlegIlyenko committed May 10, 2018
2 parents e5cb2b9 + 718e5fa commit 1b87fd1
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 4 deletions.
2 changes: 2 additions & 0 deletions src/main/scala/sangria/macros/derive/DeriveEnumSetting.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ case class RenameValue(value: String, graphqlName: String) extends DeriveEnumSet

case class IncludeValues(values: String*) extends DeriveEnumSetting
case class ExcludeValues(fieldNames: String*) extends DeriveEnumSetting

case class TransformValueNames(transformer: String String) extends DeriveEnumSetting
19 changes: 15 additions & 4 deletions src/main/scala/sangria/macros/derive/DeriveEnumTypeMacro.scala
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,17 @@ class DeriveEnumTypeMacro(context: blackbox.Context) extends {
val name = value.name.decodedName.toString.trim
val annotationName = symbolName(value.annotations)
val configName = config.collect{case MacroRenameValue(`name`, tree, _) tree}.lastOption
val actualName =
if (config.exists(_.isInstanceOf[MacroUppercaseValues]))
q"sangria.util.StringUtil.camelCaseToUnderscore(${configName orElse annotationName getOrElse q"$name"}).toUpperCase"
val actualName = {
val nonTransformedName = configName orElse annotationName getOrElse q"$name"
val transformFnOpt = config.collect{case MacroTransformValueNames(fn) fn}.lastOption
val upperCase = config.exists(_.isInstanceOf[MacroUppercaseValues])

val transformed = transformFnOpt.map(fn => q"$fn($nonTransformedName)").getOrElse(nonTransformedName)
if (upperCase)
q"sangria.util.StringUtil.camelCaseToUnderscore($transformed).toUpperCase"
else
q"${configName orElse annotationName getOrElse q"$name"}"
q"$transformed"
}

val annotationDescr = symbolDescription(value.annotations)
val configDescr = config.collect{case MacroDocumentValue(`name`, tree, _, _) tree}.lastOption
Expand Down Expand Up @@ -197,6 +203,9 @@ class DeriveEnumTypeMacro(context: blackbox.Context) extends {
case tree @ q"$setting.apply(..${values: List[String]})" if checkSetting[ExcludeValues.type](setting)
Right(MacroExcludeValues(values.toSet, tree.pos))

case tree @ q"$setting.apply($fn)" if checkSetting[TransformValueNames.type](setting)
Right(MacroTransformValueNames(fn))

case tree Left(tree.pos
"Unsupported shape of derivation config. Please define subclasses of `DeriveEnumTypeConfig` directly in the argument list of the macro.")
}
Expand All @@ -214,4 +223,6 @@ class DeriveEnumTypeMacro(context: blackbox.Context) extends {

case class MacroIncludeValues(values: Set[String], pos: Position) extends MacroDeriveEnumSetting
case class MacroExcludeValues(fieldNames: Set[String], pos: Position) extends MacroDeriveEnumSetting

case class MacroTransformValueNames(transformer: Tree) extends MacroDeriveEnumSetting
}
12 changes: 12 additions & 0 deletions src/test/scala/sangria/macros/derive/DeriveEnumTypeMacroSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,18 @@ class DeriveEnumTypeMacroSpec extends WordSpec with Matchers {
enum.values.map(_.name).sorted should be ("DARK1_BLUE_FOO_STUFF" :: "DARK_BLUE" :: "NORMAL_RED" :: Nil)
}

"allow transformation of GraphQL enum values' names" in {
val singletonEnum = deriveEnumType[Difficulty](TransformValueNames("Difficulty" + _))
val singletonEnumUpperCase = deriveEnumType[Difficulty](TransformValueNames("Difficulty" + _), UppercaseValues)
val enum = deriveEnumType[ColorAnnotated.Value](TransformValueNames("Color" + _))
val enumUpperCase = deriveEnumType[ColorAnnotated.Value](TransformValueNames("Color" + _), UppercaseValues)

singletonEnum.values.map(_.name).sorted should be ("DifficultyEasy" :: "DifficultyHard" :: "DifficultyMedium" :: Nil)
singletonEnumUpperCase.values.map(_.name).sorted should be ("DIFFICULTY_EASY" :: "DIFFICULTY_HARD" :: "DIFFICULTY_MEDIUM" :: Nil)
enum.values.map(_.name).sorted should be ("ColorDark1Blue_FooStuff" :: "ColorDarkBlue" :: "ColorNormalRed" :: Nil)
enumUpperCase.values.map(_.name).sorted should be ("COLOR_DARK1_BLUE_FOO_STUFF" :: "COLOR_DARK_BLUE" :: "COLOR_NORMAL_RED" :: Nil)
}

"allow to set name, description and deprecationReason with config" in {
val singletonEnum = deriveEnumType[Fruit](
DocumentValue("RedApple", "apple!", deprecationReason = Some("foo")),
Expand Down

0 comments on commit 1b87fd1

Please sign in to comment.