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

org.dhallj.imports.ToHeaders.scala Maven / Gradle / Ivy

The newest version!
package org.dhallj.imports

import java.util.AbstractMap.SimpleImmutableEntry
import java.util.Map.Entry
import org.dhallj.core.Expr
import org.dhallj.core.Expr.Util.{asListLiteral, asRecordLiteral, asSimpleTextLiteral}
import org.dhallj.core.typechecking.TypeCheckFailure
import org.http4s.{Header, Headers}
import org.typelevel.ci.CIString

import scala.collection.JavaConverters._

object ToHeaders {
  private val validType1: Expr = Expr.makeApplication(
    Expr.Constants.LIST,
    Expr.makeRecordType(
      Array[Entry[String, Expr]](
        new SimpleImmutableEntry("mapKey", Expr.Constants.TEXT),
        new SimpleImmutableEntry("mapValue", Expr.Constants.TEXT)
      )
    )
  )

  private val validType2: Expr = Expr.makeApplication(
    Expr.Constants.LIST,
    Expr.makeRecordType(
      Array[Entry[String, Expr]](
        new SimpleImmutableEntry("header", Expr.Constants.TEXT),
        new SimpleImmutableEntry("value", Expr.Constants.TEXT)
      )
    )
  )

  private def isValidType(expr: Expr): Boolean = {
    try {
      val tpe = Expr.Util.typeCheck(expr)

      tpe == validType1 || tpe == validType2
    } catch {
      case _: TypeCheckFailure => false
    }
  }

  // See https://discourse.dhall-lang.org/t/valid-expressions-for-using-headers/205
  // For the moment, this is consistent with the Haskell implementation
  def apply(expr: Expr): Option[Headers] =
    if (expr eq null) Some(Headers.empty)
    else {
      if (!isValidType(expr)) {
        None
      } else {
        //TODO do we need to .accept(this) on expr?
        val e = expr.normalize
        val l = asListLiteral(e)
        if (l eq null) {
          Some(Headers.empty)
        } else {
          val hs: List[Header.Raw] = l.asScala.toList.flatMap { e =>
            // e should have type `List { header : Text, value Text }`
            // or `List { mapKey : Text, mapValue Text }`
            val r = asRecordLiteral(e)
            if (r eq null) {
              None
            } else {
              if (r.size == 2) {
                val map = r.asScala.map(e => e.getKey -> e.getValue).toMap
                if (map.contains("header") && map.contains("value")) {
                  val key = asSimpleTextLiteral(map("header"))
                  val value = asSimpleTextLiteral(map("value"))

                  if ((key ne null) && (value ne null)) {
                    Some(Header.Raw(CIString(key), value))
                  } else None
                } else if (map.contains("mapKey") && map.contains("mapValue")) {
                  val key = asSimpleTextLiteral(map("mapKey"))
                  val value = asSimpleTextLiteral(map("mapValue"))

                  if ((key ne null) && (value ne null)) {
                    Some(Header.Raw(CIString(key), value))
                  } else None
                } else None
              } else None
            }
          }
          Some(Headers(hs))
        }
      }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy