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

sttp.tapir.macros.ValidatorMacros.scala Maven / Gradle / Ivy

package sttp.tapir.macros

import sttp.tapir.internal.EnumerationMacros.*
import sttp.tapir.Validator
import sttp.tapir.Schema

import scala.quoted.*

trait ValidatorMacros {

  /** Creates an enum validator for an `enum` where all cases are parameterless, or where all subtypes of the sealed hierarchy `T` are
    * `object`s. This enumeration will only be used for documentation, as a value outside of the allowed values will not be decoded in the
    * first place (the decoder has no other option than to fail).
    */
  inline def derivedEnumeration[T]: Validator.Enumeration[T] = ${ ValidatorMacros.derivedEnumerationImpl[T] }
}

private[tapir] object ValidatorMacros {
  def derivedEnumerationImpl[T: Type](using q: Quotes): Expr[Validator.Enumeration[T]] = {
    import quotes.reflect.*

    val tpe = TypeRepr.of[T]
    val symbol = tpe.typeSymbol

    if (!symbol.isClassDef || !(symbol.flags is Flags.Sealed)) {
      report.errorAndAbort("Can only enumerate values of a sealed trait, class or enum.")
    }

    val instances = enumerationTypeChildren[T](failOnError = true)
      .flatMap(_.toList)
      .distinct
      .sortBy(_.name)
      .map(x =>
        tpe.memberType(x).asType match {
          case '[f] => Ref(x).asExprOf[f]
        }
      )
    val name = '{ Option(Schema.SName(${ Expr(symbol.fullName) })) }

    '{
      Validator.Enumeration[T](
        List(${ Varargs(instances) }: _*).asInstanceOf[List[T]],
        None,
        ${ name }
      )
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy