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

o-deps.proto-purs_2.11.2.1.3.io.github.zero-deps.proto-tex_3.2.1.3.source-code.main.scala Maven / Gradle / Ivy

The newest version!
package proto
package tex

import scala.quoted.*
import scala.collection.SortedMap

case class GenRes(
    doc: String
  , argsExamples: String
  )

case class GenResRaw(
    doc: List[String]
  , argsExamples: List[String]
  ) {
    def toGenRes: GenRes =
      val doc = this.doc.mkString
      val argsExamples = this.argsExamples.mkString
      GenRes(
        doc = doc
      , argsExamples = argsExamples
      )
  }

inline def generate[D, E](
    inline category: Map[Int, String], inline ask: String, inline ok: String, inline err: String
  ): GenRes = 
    ${Macro.generate[D, E]('category, 'ask, 'ok, 'err)}

object Macro:
  def generate[D: Type, E: Type](
      category: Expr[Map[Int, String]]
    , ask: Expr[String]
    , ok: Expr[String]
    , err: Expr[String]
    )(using qctx: Quotes): Expr[GenRes] = 
    Impl().generate[D, E](category, ask, ok, err)
end Macro

private class Impl(using val qctx: Quotes) extends Ops with Doc:
  import qctx.reflect.*

  def generate[D: Type, E: Type](
      category: Expr[Map[Int, String]]
    , ask: Expr[String]
    , ok: Expr[String]
    , err: Expr[String]
    ): Expr[GenRes] =

    val tpeD = TypeRepr.of[D]
    val tpeE = TypeRepr.of[E]

    val decodeTpes = collectTpes(tpeD)
    val encodeTpes = collectTpes(tpeE)

    val commonTpes = encodeTpes intersect decodeTpes

    val childrenD = findChildren(tpeD)
    val childrenE = findChildren(tpeE)
    val messages = childrenD ++ childrenE
    val others = messages.map(_.tpe).flatMap(x => type_to_tpe(x)._1) match {
      case x +: xs =>
        collectTpes(head=x, tail=xs, acc=Nil, firstLevel=false)
      case Nil => Nil
    }

    val sorted: SortedMap[Int, String] = SortedMap.from(category.valueOrAbort.toList)
    val categoryFun: Int => String = number => {
      sorted.collectFirst{ case (n, cat) if number < n => cat }.getOrElse("???")
    }

    val doc = 
      Expr.ofList(
        tex1(messages=messages, others=others, category=categoryFun, ask=ask.valueOrAbort, ok=ok.valueOrAbort, err=err.valueOrAbort)
          .grouped(1024)
          .toList
          .map(Expr.apply)
      )
    
    val argsExamples = 
      Expr.ofList(
        examples(childrenE, commonTpes.map(_.tpe))
          .grouped(1024)
          .toList
          .map(Expr.apply)
      )

    '{
      GenResRaw(
        doc = ${doc}
      , argsExamples = ${argsExamples}
      ).toGenRes
    }
end Impl




© 2015 - 2024 Weber Informatics LLC | Privacy Policy