Skip to content

Commit

Permalink
adding validations annotation to macros (#297)
Browse files Browse the repository at this point in the history
* adding validations annotation to macros

* fixed fmt error
  • Loading branch information
AppleKid7 authored Jul 15, 2022
1 parent 58c79f1 commit fac9561
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,26 @@ object DeriveSchema {
.filter(_ != EmptyTree)
}.getOrElse(Nil)

@nowarn
val fieldValidations: List[Tree] =
tpe.typeSymbol.asClass.primaryConstructor.asMethod.paramLists.headOption.map { symbols =>
symbols.map { symbol =>
symbol.annotations.collect {
case annotation if (annotation.tree.tpe.toString.startsWith("zio.schema.annotation.validate")) =>
annotation.tree match {
case q"new $annConstructor(..$annotationArgs)" =>
q"..$annotationArgs"
case tree =>
c.warning(c.enclosingPosition, s"Unhandled annotation tree $tree")
EmptyTree
}
}
}.filter(_ != EmptyTree)
.map(_.foldLeft[c.universe.Tree](q"zio.schema.validation.Validation.succeed") {
case (acc, t) => q"$acc && $t"
})
}.getOrElse(Nil)

if (arity > 22) {
val fields = fieldTypes.zip(fieldAnnotations).map {
case (termSymbol, annotations) =>
Expand Down Expand Up @@ -284,8 +304,8 @@ object DeriveSchema {
case 22 => q"zio.schema.Schema.CaseClass22[..$typeArgs]"
}

val fieldDefs = fieldTypes.zip(fieldAnnotations).zipWithIndex.map {
case ((termSymbol, annotations), idx) =>
val fieldDefs = fieldTypes.zip(fieldAnnotations).zip(fieldValidations).zipWithIndex.map {
case (((termSymbol, annotations), validation), idx) =>
val fieldSchema = directInferSchema(
tpe,
concreteType(tpe, termSymbol.typeSignature),
Expand All @@ -295,9 +315,9 @@ object DeriveSchema {
val fieldLabel = termSymbol.name.toString.trim

if (annotations.nonEmpty)
q"""$fieldArg = zio.schema.Schema.Field.apply(label = $fieldLabel, schema = $fieldSchema, annotations = zio.Chunk.apply[Any](..$annotations))"""
q"""$fieldArg = zio.schema.Schema.Field.apply(label = $fieldLabel, schema = $fieldSchema, annotations = zio.Chunk.apply[Any](..$annotations), validation = $validation)"""
else
q"""$fieldArg = zio.schema.Schema.Field.apply(label = $fieldLabel, schema = $fieldSchema)"""
q"""$fieldArg = zio.schema.Schema.Field.apply(label = $fieldLabel, schema = $fieldSchema, validation = $validation)"""
}

val constructArgs = fieldTypes.zipWithIndex.map {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,10 +217,19 @@ private case class DeriveSchema()(using val ctx: Quotes) extends ReflectionUtils

// Derive Field for a CaseClass
def deriveField(repr: TypeRepr, label: String, anns: List[Expr[Any]], stack: Stack) = {
import zio.schema.validation.Validation
repr.asType match { case '[t] =>
val schema = deriveSchema[t](stack)
val validators = anns.collect {
case ann if ann.isExprOf[Validation[t]] => ann.asExprOf[Validation[t]]
}
val validator: Expr[Validation[t]] = validators.foldLeft[Expr[Validation[t]]]('{Validation.succeed}){
case (acc, expr) => '{
$acc && $expr
}
}
val chunk = '{ zio.Chunk.fromIterable(${ Expr.ofSeq(anns.reverse) }) }
'{ Field(${Expr(label)}, $schema, $chunk) }
'{ Field(${Expr(label)}, $schema, $chunk, $validator) }
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package zio.schema.annotation

import zio.schema.validation.Validation

final case class validate[A](validation: Validation[A]) extends scala.annotation.StaticAnnotation
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ object Validation extends Regexs with Time {
def lessThan[A](value: A)(implicit numType: NumType[A]): Validation[A] =
Validation(Bool.Leaf(Num.LessThan(numType, value)))

def between[A](lower: A, upper: A)(implicit numType: NumType[A]): Validation[A] =
(greaterThan(lower) || equalTo(lower)) && ((lessThan(upper) || equalTo(upper)))

def equalTo[A](value: A)(implicit numType: NumType[A]): Validation[A] =
Validation(Bool.Leaf(Num.EqualTo(numType, value)))

Expand Down

0 comments on commit fac9561

Please sign in to comment.