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

org.json4s.json_writers.scala Maven / Gradle / Ivy

There is a newer version: 4.1.0-M8
Show newest version
package org.json4s

import scala.collection.mutable.ListBuffer
import org.json4s.JsonAST._

object JsonWriter {
  def ast: JsonWriter[JValue] = new JDoubleAstRootJsonWriter
  def bigDecimalAst: JsonWriter[JValue] = new JDecimalAstRootJsonWriter
  def streaming[T <: java.io.Writer](writer: T, alwaysEscapeUnicode: Boolean): JsonWriter[T] =
    new RootStreamingJsonWriter[T](writer, pretty = false, alwaysEscapeUnicode = alwaysEscapeUnicode)
  def streamingPretty[T <: java.io.Writer](writer: T, alwaysEscapeUnicode: Boolean): JsonWriter[T] =
    new RootStreamingJsonWriter[T](writer, pretty = true, alwaysEscapeUnicode = alwaysEscapeUnicode)
}
trait JsonWriter[T] {
  def startArray(): JsonWriter[T]
  def endArray(): JsonWriter[T]
  def startObject(): JsonWriter[T]
  def endObject(): JsonWriter[T]
  def string(value: String): JsonWriter[T]
  def byte(value: Byte): JsonWriter[T]
  def int(value: Int): JsonWriter[T]
  def long(value: Long): JsonWriter[T]
  def bigInt(value: BigInt): JsonWriter[T]
  def boolean(value: Boolean): JsonWriter[T]
  def short(value: Short): JsonWriter[T]
  def float(value: Float): JsonWriter[T]
  def double(value: Double): JsonWriter[T]
  def bigDecimal(value: BigDecimal): JsonWriter[T]
  def startField(name: String): JsonWriter[T]
  def result: T

  def addJValue(jv: JValue): JsonWriter[T]
}
private final class JDoubleJFieldJsonWriter(name: String, parent: JDoubleJObjectJsonWriter)
  extends JDoubleAstJsonWriter {
  def result: JValue = JNothing

  def addNode(node: JValue): JsonWriter[JValue] = parent.addNode(name -> node)

}
private final class JDoubleAstRootJsonWriter extends JDoubleAstJsonWriter {
  private[this] var nodes = List.empty[JValue]

  def addNode(node: JValue): JsonWriter[JValue] = {
    nodes ::= node
    this
  }
  def result: JValue = {
    if (nodes.nonEmpty) nodes.head else JNothing
  }
}
private final class JDecimalJFieldJsonWriter(name: String, parent: JDecimalJObjectJsonWriter)
  extends JDecimalAstJsonWriter {
  def result: JValue = JNothing

  def addNode(node: JValue): JsonWriter[JValue] = parent.addNode(name -> node)

}
private final class JDecimalAstRootJsonWriter extends JDecimalAstJsonWriter {
  private[this] var nodes = List.empty[JValue]

  def addNode(node: JValue): JsonWriter[JValue] = {
    nodes ::= node
    this
  }
  def result: JValue = {
    if (nodes.nonEmpty) nodes.head else JNothing
  }
}
private final class JDoubleJObjectJsonWriter(parent: JsonWriter[JValue]) extends JsonWriter[JValue] {
  private[this] val nodes = ListBuffer[JField]()
  def addNode(node: JField): JDoubleJObjectJsonWriter = {
    nodes += node
    this
  }
  def startArray(): JsonWriter[JValue] = {
    sys.error(
      "You have to start a field to be able to end it (startArray called before startField in a JObject builder)"
    )
  }

  def endArray(): JsonWriter[JValue] =
    sys.error("You have to start an array to be able to end it (endArray called before startArray)")

  def startObject(): JsonWriter[JValue] =
    sys.error(
      "You have to start a field to be able to end it (startObject called before startField in a JObject builder)"
    )

  def endObject(): JsonWriter[JValue] = {
    parent match {
      case p: JDoubleAstJsonWriter => p.addNode(result)
      case _ => parent
    }
  }

  def string(value: String): JsonWriter[JValue] =
    sys.error("You have to start a field to be able to end it (string called before startField in a JObject builder)")

  def byte(value: Byte): JsonWriter[JValue] =
    sys.error("You have to start a field to be able to end it (byte called before startField in a JObject builder)")

  def int(value: Int): JsonWriter[JValue] =
    sys.error("You have to start a field to be able to end it (int called before startField in a JObject builder)")

  def long(value: Long): JsonWriter[JValue] =
    sys.error("You have to start a field to be able to end it (long called before startField in a JObject builder)")

  def bigInt(value: BigInt): JsonWriter[JValue] =
    sys.error("You have to start a field to be able to end it (bigInt called before startField in a JObject builder)")

  def boolean(value: Boolean): JsonWriter[JValue] =
    sys.error("You have to start a field to be able to end it (boolean called before startField in a JObject builder)")

  def short(value: Short): JsonWriter[JValue] =
    sys.error("You have to start a field to be able to end it (short called before startField in a JObject builder)")

  def float(value: Float): JsonWriter[JValue] =
    sys.error("You have to start a field to be able to end it (float called before startField in a JObject builder)")

  def double(value: Double): JsonWriter[JValue] =
    sys.error("You have to start a field to be able to end it (double called before startField in a JObject builder)")

  def bigDecimal(value: BigDecimal): JsonWriter[JValue] =
    sys.error(
      "You have to start a field to be able to end it (bigDecimal called before startField in a JObject builder)"
    )

  def startField(name: String): JsonWriter[JValue] = new JDoubleJFieldJsonWriter(name, this)

  def addJValue(jv: JValue): JsonWriter[JValue] =
    sys.error(
      "You have to start a field to be able to end it (addJValue called before startField in a JObject builder)"
    )

  def result: JValue = JObject(nodes.toList)
}
private final class JDecimalJObjectJsonWriter(parent: JsonWriter[JValue]) extends JsonWriter[JValue] {
  private[this] val nodes = ListBuffer[JField]()
  def addNode(node: JField): JDecimalJObjectJsonWriter = {
    nodes += node
    this
  }
  def startArray(): JsonWriter[JValue] = {
    sys.error(
      "You have to start a field to be able to end it (startArray called before startField in a JObject builder)"
    )
  }

  def endArray(): JsonWriter[JValue] =
    sys.error("You have to start an array to be able to end it (endArray called before startArray)")

  def startObject(): JsonWriter[JValue] =
    sys.error(
      "You have to start a field to be able to end it (startObject called before startField in a JObject builder)"
    )

  def endObject(): JsonWriter[JValue] = {
    parent match {
      case p: JDecimalAstJsonWriter => p.addNode(result)
      case _ => parent
    }
  }

  def string(value: String): JsonWriter[JValue] =
    sys.error("You have to start a field to be able to end it (string called before startField in a JObject builder)")

  def byte(value: Byte): JsonWriter[JValue] =
    sys.error("You have to start a field to be able to end it (byte called before startField in a JObject builder)")

  def int(value: Int): JsonWriter[JValue] =
    sys.error("You have to start a field to be able to end it (int called before startField in a JObject builder)")

  def long(value: Long): JsonWriter[JValue] =
    sys.error("You have to start a field to be able to end it (long called before startField in a JObject builder)")

  def bigInt(value: BigInt): JsonWriter[JValue] =
    sys.error("You have to start a field to be able to end it (bigInt called before startField in a JObject builder)")

  def boolean(value: Boolean): JsonWriter[JValue] =
    sys.error("You have to start a field to be able to end it (boolean called before startField in a JObject builder)")

  def short(value: Short): JsonWriter[JValue] =
    sys.error("You have to start a field to be able to end it (short called before startField in a JObject builder)")

  def float(value: Float): JsonWriter[JValue] =
    sys.error("You have to start a field to be able to end it (float called before startField in a JObject builder)")

  def double(value: Double): JsonWriter[JValue] =
    sys.error("You have to start a field to be able to end it (double called before startField in a JObject builder)")

  def bigDecimal(value: BigDecimal): JsonWriter[JValue] =
    sys.error(
      "You have to start a field to be able to end it (bigDecimal called before startField in a JObject builder)"
    )

  def startField(name: String): JsonWriter[JValue] = new JDecimalJFieldJsonWriter(name, this)

  def addJValue(jv: JValue): JsonWriter[JValue] =
    sys.error(
      "You have to start a field to be able to end it (addJValue called before startField in a JObject builder)"
    )

  def result: JValue = JObject(nodes.toList: _*)
}

private final class JDoubleJArrayJsonWriter(parent: JsonWriter[JValue]) extends JDoubleAstJsonWriter {
  private[this] val nodes = ListBuffer[JValue]()
  def addNode(node: JValue): JsonWriter[JValue] = {
    nodes += node
    this
  }

  override def endArray(): JsonWriter[JValue] = {
    parent match {
      case m: JDoubleAstJsonWriter => m.addNode(result)
      case _ => parent
    }
  }

  def result: JValue = JArray(nodes.toList)
}

private final class JDecimalJArrayJsonWriter(parent: JsonWriter[JValue]) extends JDecimalAstJsonWriter {
  private[this] val nodes = ListBuffer[JValue]()
  def addNode(node: JValue): JsonWriter[JValue] = {
    nodes += node
    this
  }

  override def endArray(): JsonWriter[JValue] = {
    parent match {
      case m: JDecimalAstJsonWriter => m.addNode(result)
      case _ => parent
    }
  }

  def result: JValue = JArray(nodes.toList)
}
private sealed abstract class JValueJsonWriter extends JsonWriter[JValue] {

  def addNode(node: JValue): JsonWriter[JValue]

  def endObject(): JsonWriter[JValue] = {
    sys.error("You have to start an object to be able to end it (endObject called before startObject)")
  }

  def startField(name: String): JsonWriter[JValue] = {
    sys.error("You have to start an object before starting a field.")
  }

  def string(value: String): JsonWriter[JValue] = addNode(JString(value))

  def byte(value: Byte): JsonWriter[JValue] = addNode(JInt(value: Long))

  def int(value: Int): JsonWriter[JValue] = addNode(JInt(value))

  def long(value: Long): JsonWriter[JValue] = addNode(JInt(value))

  def bigInt(value: BigInt): JsonWriter[JValue] = addNode(JInt(value))

  def boolean(value: Boolean): JsonWriter[JValue] = addNode(JBool(value))

  def short(value: Short): JsonWriter[JValue] = addNode(JInt(value: Long))

  def endArray(): JsonWriter[JValue] = {
    sys.error("You have to start an object to be able to end it (endArray called before startArray)")
  }

  def addJValue(jv: JValue): JsonWriter[JValue] = addNode(jv)

}
private sealed abstract class JDoubleAstJsonWriter extends JValueJsonWriter {
  def startArray(): JsonWriter[JValue] = {
    new JDoubleJArrayJsonWriter(this)
  }

  def startObject(): JsonWriter[JValue] = {
    new JDoubleJObjectJsonWriter(this)
  }

  def float(value: Float): JsonWriter[JValue] = addNode(JDouble(value))

  def double(value: Double): JsonWriter[JValue] = addNode(JDouble(value))

  def bigDecimal(value: BigDecimal): JsonWriter[JValue] = addNode(JDouble(value.doubleValue))
}

private sealed abstract class JDecimalAstJsonWriter extends JValueJsonWriter {
  def startArray(): JsonWriter[JValue] = {
    new JDecimalJArrayJsonWriter(this)
  }

  def startObject(): JsonWriter[JValue] = {
    new JDecimalJObjectJsonWriter(this)
  }

  def float(value: Float): JsonWriter[JValue] = double(value.toDouble)

  def double(value: Double): JsonWriter[JValue] = addNode(JDecimal(BigDecimal(value)))

  def bigDecimal(value: BigDecimal): JsonWriter[JValue] = addNode(JDecimal(value))

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy