All Downloads are FREE. Search and download functionalities are using the official Maven repository.

caliban.client.__Value.scala Maven / Gradle / Ivy

There is a newer version: 1.3.3.4
Show newest version
package caliban.client

import io.circe.{ Decoder, Encoder, Json }

/**
 * Value that can be returned by the server or sent as an argument.
 */
sealed trait __Value { self =>
  def dropNullValues: __Value = self match {
    case __Value.__ListValue(values)   => __Value.__ListValue(values.map(_.dropNullValues))
    case __Value.__ObjectValue(fields) =>
      __Value.__ObjectValue(fields.flatMap { case (name, value) =>
        value match {
          case __Value.__NullValue => None
          case _                   => Some(name -> value.dropNullValues)
        }
      })
    case _                             => self
  }
}

object __Value {
  case object __NullValue                                   extends __Value {
    override def toString: String = "null"
  }
  case class __NumberValue(value: BigDecimal)               extends __Value {
    override def toString: String = s"$value"
  }
  case class __EnumValue(value: String)                     extends __Value {
    override def toString: String = value
  }
  case class __StringValue(value: String)                   extends __Value {
    override def toString: String = Json.fromString(value).toString
  }
  case class __BooleanValue(value: Boolean)                 extends __Value {
    override def toString: String = value.toString
  }
  case class __ListValue(values: List[__Value])             extends __Value {
    override def toString: String = values.map(_.toString).mkString("[", ",", "]")
  }
  case class __ObjectValue(fields: List[(String, __Value)]) extends __Value {
    override def toString: String =
      fields.map { case (name, value) => s"""$name:${value.toString}""" }.mkString("{", ",", "}")
  }

  private def jsonToValue(json: Json): __Value =
    json.fold(
      __NullValue,
      __BooleanValue.apply,
      number => __NumberValue(number.toBigDecimal getOrElse BigDecimal(number.toDouble)),
      __StringValue.apply,
      array => __Value.__ListValue(array.toList.map(jsonToValue)),
      obj => __Value.__ObjectValue(obj.toList.map { case (k, v) => k -> jsonToValue(v) })
    )

  private def valueToJson(a: __Value): Json = a match {
    case `__NullValue`         => Json.Null
    case __NumberValue(value)  => Json.fromBigDecimal(value)
    case __StringValue(value)  => Json.fromString(value)
    case __EnumValue(value)    => Json.fromString(value)
    case __BooleanValue(value) => Json.fromBoolean(value)
    case __ListValue(values)   => Json.fromValues(values.map(valueToJson))
    case __ObjectValue(fields) => Json.obj(fields.map { case (k, v) => k -> valueToJson(v) }: _*)
  }

  implicit val valueDecoder: Decoder[__Value] = Decoder.instance(hcursor => Right(jsonToValue(hcursor.value)))

  implicit val valueEncoder: Encoder[__Value] = (a: __Value) => valueToJson(a)
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy