Created
May 5, 2017 09:08
-
-
Save dgouyette/2777b950dbf209acc5ef6881a821af41 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import jto.validation._ | |
sealed trait Color | |
object Color { | |
case object Red extends Color | |
case object Orange extends Color | |
case object Green extends Color | |
val colorR : Rule[String, Color] = Rule.fromMapping { | |
case "Red" => Valid(Red) | |
case "Orange" => Valid(Orange) | |
case "Green" => Valid(Green) | |
case other => Invalid(Seq(ValidationError("unhandled.value", other))) | |
} | |
} | |
Color.colorR.validate("aaa")//Invalid(List((/,List(ValidationError(List(unhandled.value),WrappedArray(aaa)))))) | |
Color.colorR.validate("Red")//Valid(Red) |
It's work with this version :
package validation
import scala.meta._
import collection.immutable.Seq
object Hierarchy {
def inherits(superType: Type.Name)(cls: Defn.Object): Boolean =
cls.templ.parents.headOption.exists {
case q"$parent()" => parent.syntax == superType.syntax
case _ => false
}
def isSealed(mods: Seq[Mod]): Boolean = mods.exists(_.syntax == "sealed")
}
class Reader extends scala.annotation.StaticAnnotation {
inline def apply(defn: Any): Any = meta {
defn match {
case Term.Block(Seq(t@ClassOrTrait(mods, name), companion: Defn.Object)) if Hierarchy.isSealed(mods) =>
val oldTemplStats = companion.templ.stats.getOrElse(Nil)
val cases = oldTemplStats.collect{
case t: Defn.Object =>
val name = t.name.value
val term = q"""cats.data.Validated.Valid(${t.name}) """
p"""case ${Lit.String(name)} => $term """
}
val plus =
q"""implicit val rule : jto.validation.Rule[String,$name] = jto.validation.Rule.fromMapping {
..case $cases
}"""
val updatedCompanion = companion.copy(templ = companion.templ.copy(stats = Some(oldTemplStats:+plus)))
val resul = Term.Block(Seq(t, updatedCompanion))
println("------------")
println(resul.syntax)
println("------------")
resul
case _ => abort("Reader must annotate sealed trait")
}
}
}
object ClassOrTrait {
def unapply(any: Defn): Option[(Seq[Mod], Type.Name)] = any match {
case t: Defn.Class => Some((t.mods, t.name))
case t: Defn.Trait => Some((t.mods, t.name))
case _ => None
}
}
ça vaudrait le coup de regarder dans contrib si il y a pas des trucs a réutiliser plutôt que de les redéfinir je pense en particulier a Class Or Trait ou a Hierarchy
genre https://github.com/scalameta/scalameta/blob/master/scalameta/contrib/shared/src/main/scala/scala/meta/contrib/TreeOps.scala#L58 pour hierarchy .. ?
Bonne idée. Maintenant que cela fonctionne, je vais essayer de simplifier mon code.
Merci pour l'info
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Avec le code ci dessous, j'obtiens le code suivant :
Si tu as une idée pour applatir les cases, je suis preneur