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

dependency.literal.Mappings.scala Maven / Gradle / Ivy

The newest version!
package dependency.literal

import java.util.UUID

import scala.quoted.{Expr => QExpr, _}

private[literal] final case class Mappings(mappings: List[(String, QExpr[String])]) {


  def input(inputs: Seq[String]): String =
    (inputs.zip(mappings).flatMap { case (s, (id, _)) => Seq(s, id) } ++ inputs.drop(mappings.length)).mkString


  private def indices(str: String, subString: String): List[Int] = {
    def helper(from: Int): List[Int] = {
      val idx = str.indexOf(subString, from)
      if (idx < 0) Nil
      else idx :: helper(idx + subString.length)
    }
    helper(0)
  }

  private def insertExpr(str: String, substitutions: List[(Int, Int, QExpr[String])])(using Quotes): QExpr[String] =
    substitutions match {
      case Nil => QExpr(str)
      case (idx, idLen, insert) :: tail =>
        val (prefix, suffix) = str.splitAt(idx)
        val prefixExpr = insertExpr(prefix, tail)
        '{$prefixExpr + $insert + ${QExpr(suffix.substring(idLen))}}
    }

  def Expr(str: String)(using Quotes): QExpr[String] = {

    val substitutions = mappings
      .flatMap {
        case (id, expr) =>
          val indices0 = indices(str, id)
          indices0.map(idx => (idx, id.length, expr))
      }
      .sortBy(-_._1)

    insertExpr(str, substitutions)
  }

  def stringOption(opt: Option[String])(using Quotes): QExpr[Option[String]] =
    opt match {
      case None => '{None}
      case Some(value) => '{Some(${Expr(value)})}
    }
  def mapStringString(map: Map[String, String])(using Quotes): QExpr[Map[String, String]] = {
    val entries = map.toVector.sorted.map {
      case (k, v) => '{(${Expr(k)}, ${Expr(v)})}
    }
    '{Map(${Varargs(entries)}: _*)}
  }

  def seqStringStringOption(seq: Seq[(String, Option[String])])(using Quotes): QExpr[Seq[(String, Option[String])]] = {
    val entries = seq.map {
      case (k, v) => '{(${Expr(k)}, ${stringOption(v)})}
    }
    '{Seq(${Varargs(entries)}: _*)}
  }

}

object Mappings {
  def from(inputs: Seq[String], argsExpr: QExpr[Seq[Any]])(using Quotes): Mappings = {
    val mappings = (0 until (inputs.length - 1)).toList.map { idx =>
      val id = UUID.randomUUID().toString.filter(_ != '-')
      (id, '{${argsExpr}.apply(${QExpr(idx)}).toString})
    }
    Mappings(mappings)
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy