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

com.dslplatform.json.runtime.ScalaCollectionAnalyzer.scala Maven / Gradle / Ivy

The newest version!
package com.dslplatform.json
package runtime

import java.lang.reflect.{ParameterizedType, Type}

import scala.collection.mutable

object ScalaCollectionAnalyzer {
  val Reader: DslJson.ConverterFactory[JsonReader.ReadObject[_]] = (manifest: Type, dslJson: DslJson[_]) => {
    manifest match {
      case cl: Class[_] =>
        analyzeDecoding(manifest, classOf[AnyRef], cl, dslJson).orNull
      case pt: ParameterizedType if pt.getActualTypeArguments.length == 1 =>
        pt.getRawType match {
          case rc: Class[_] =>
            analyzeDecoding(manifest, pt.getActualTypeArguments.head, rc, dslJson).orNull
          case _ =>
            null
        }
      case _ => null
    }
  }
  val Writer: DslJson.ConverterFactory[JsonWriter.WriteObject[_]] = (manifest: Type, dslJson: DslJson[_]) => {
    manifest match {
      case cl: Class[_] =>
        analyzeEncoding(manifest, classOf[AnyRef], cl, dslJson).orNull
      case pt: ParameterizedType if pt.getActualTypeArguments.length == 1 =>
        pt.getRawType match {
          case rc: Class[_] =>
            analyzeEncoding(manifest, pt.getActualTypeArguments.head, rc, dslJson).orNull
          case _ =>
            null
        }
      case _ =>
        null
    }
  }

  private def analyzeDecoding(
    manifest: Type,
    element: Type,
    collection: Class[_],
    json: DslJson[_]): Option[ArrayBufferDecoder[_]] = {

    if (!classOf[scala.collection.Iterable[_]].isAssignableFrom(collection)) None
    else {
      Option(json.tryFindReader(element)) match {
        case Some(reader: JsonReader.ReadObject[Any @unchecked]) =>
          ScalaConversionMapping.collectionConversion(collection) match {
            case Some(conversion) =>
              val decoder = new ArrayBufferDecoder[Any](manifest, reader, conversion.emptyInstance, conversion.fromBuffer)
              json.registerReader(manifest, decoder)
              Some(decoder)
            case _ =>
              None
          }
        case _ => None
      }
    }
  }

  case class CollectionConversion(
    emptyInstance: () => scala.collection.Iterable[Any],
    fromBuffer: mutable.ArrayBuffer[Any] => scala.collection.Iterable[Any]
  )

  private def analyzeEncoding(manifest: Type, element: Type, collection: Class[_], json: DslJson[_]) = {
    if (!classOf[scala.collection.Iterable[_]].isAssignableFrom(collection)) None
    else {
      if (classOf[AnyRef] == element) {
        val encoder = new IterableEncoder[Any](json, None)
        json.registerWriter(manifest, encoder)
        Some(encoder)
      } else {
        Option(json.tryFindWriter(element)) match {
          case Some(writer: JsonWriter.WriteObject[Any @unchecked]) =>
            val encoder = new IterableEncoder[Any](json, Option(writer))
            json.registerWriter(manifest, encoder)
            Some(encoder)
          case _ =>
            None
        }
      }
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy