package sangria.validation.rules.experimental.overlappingfields import java.util import java.util.{Comparator, Objects} import sangria.ast import sangria.renderer.QueryRenderer /** * A hashable representation of field name and arguments, * used to check uniqueness of them in a set of fields * * Two fields also have the same name and arguments when * the order of arguments differs. */ final class FieldNameAndArguments(private val field: ast.Field) { private val fieldName: String = field.name private val arguments: util.ArrayList[(String, String)] = argumentsKey(field.arguments) override val hashCode: Int = { Objects.hash(fieldName, arguments) } override def equals(obj: Any): Boolean = { obj match { case other: FieldNameAndArguments => fieldName == other.fieldName && arguments == other.arguments case _ => false } } def conflictReason(other: FieldNameAndArguments): String = { if (fieldName != other.fieldName) { s"'$fieldName' and '${other.fieldName}' are different fields" } else if (arguments != other.arguments) { "of differing arguments" } else { throw new IllegalArgumentException("no conflict between keys") } } private def argumentsKey(arguments: Vector[ast.Argument]): util.ArrayList[(String, String)] = { val key = new util.ArrayList[(String, String)](arguments.size) arguments.foreach { argument => key.add(argument.name -> QueryRenderer.render(argument.value, QueryRenderer.Compact)) } key.sort(new Comparator[(String, String)] { override def compare(a: (String, String), b: (String, String)): Int = a._1.compareTo(b._1) }) key } }