allow parsing block
This commit is contained in:
parent
2d30969ec5
commit
26572ffa0d
2 changed files with 60 additions and 18 deletions
|
@ -69,7 +69,7 @@ private given FromExpr[Property] with {
|
|||
} =>
|
||||
Some(Property(a, n, r, v))
|
||||
case o =>
|
||||
println(s"Canot extrat ${o.show}:${x}")
|
||||
println(s"Cannot extrat ${o.show}")
|
||||
None
|
||||
}
|
||||
}
|
||||
|
@ -252,23 +252,54 @@ extension (e: Expr[Any]) {
|
|||
}
|
||||
}
|
||||
|
||||
given astFromExpr: FromExpr[Ast] = new FromExpr[Ast] {
|
||||
private def fromBlock(using
|
||||
Quotes
|
||||
)(block: quotes.reflect.Block): Option[Ast] = {
|
||||
import quotes.reflect.*
|
||||
val empty: Option[List[Ast]] = Some(Nil)
|
||||
val stmts = block.statements.foldLeft(empty) { (r, stmt) =>
|
||||
stmt match {
|
||||
case ValDef(n, _, Some(body)) =>
|
||||
r.flatMap { astList =>
|
||||
body.asExprOf[Ast].value.map { v =>
|
||||
astList :+ v
|
||||
}
|
||||
}
|
||||
|
||||
def unapply(e: Expr[Ast])(using Quotes): Option[Ast] = {
|
||||
|
||||
extractTerm(e.toTerm).asExpr match {
|
||||
case '{ $x: Query } => x.value
|
||||
case '{ $x: ScalarValueLift } => x.value
|
||||
case '{ $x: Property } => x.value
|
||||
case '{ $x: Ident } => x.value
|
||||
case '{ $x: Tuple } => x.value
|
||||
case '{ $x: Constant } => x.value
|
||||
case '{ $x: Operation } => x.value
|
||||
case '{ $x: Ordering } => x.value
|
||||
case '{ $x: Action } => x.value
|
||||
case '{ $x: If } => x.value
|
||||
case '{ $x: Infix } => x.value
|
||||
case o => None
|
||||
case o =>
|
||||
None
|
||||
}
|
||||
}
|
||||
stmts.flatMap { stmts =>
|
||||
block.expr.asExprOf[Ast].value.map { last =>
|
||||
minisql.ast.Block(stmts :+ last)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
given astFromExpr: FromExpr[Ast] = new FromExpr[Ast] {
|
||||
|
||||
def unapply(e: Expr[Ast])(using Quotes): Option[Ast] = {
|
||||
val et = extractTerm(e.toTerm)
|
||||
et match {
|
||||
case b: quotes.reflect.Block => fromBlock(b)
|
||||
case b: quotes.reflect.Ident => Some(Ident(b.name))
|
||||
case o =>
|
||||
o.asExpr match {
|
||||
case '{ $x: Query } => x.value
|
||||
case '{ $x: ScalarValueLift } => x.value
|
||||
case '{ $x: Property } => x.value
|
||||
case '{ $x: Ident } => x.value
|
||||
case '{ $x: Tuple } => x.value
|
||||
case '{ $x: Constant } => x.value
|
||||
case '{ $x: Operation } => x.value
|
||||
case '{ $x: Ordering } => x.value
|
||||
case '{ $x: Action } => x.value
|
||||
case '{ $x: If } => x.value
|
||||
case '{ $x: Infix } => x.value
|
||||
case o => None
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package minisql.dsl
|
||||
|
||||
import minisql.ast.{Ast, Entity, given}
|
||||
import minisql.ast.{Ast, Entity, Map, Property, Ident, given}
|
||||
import scala.quoted.*
|
||||
import scala.compiletime.*
|
||||
import scala.compiletime.ops.string.*
|
||||
|
@ -13,6 +13,11 @@ trait Query[E] extends Dsl
|
|||
|
||||
class EntityQuery[E](val ast: Ast) extends Query
|
||||
|
||||
extension [E](inline e: EntityQuery[E]) {
|
||||
inline def mapAst[E1](inline f: Ast => Ast): EntityQuery[E1] =
|
||||
EntityQuery[E1](f(e.ast))
|
||||
}
|
||||
|
||||
given FromExpr[EntityQuery[?]] with {
|
||||
def unapply(x: Expr[EntityQuery[?]])(using Quotes): Option[EntityQuery[?]] = {
|
||||
x match {
|
||||
|
@ -44,3 +49,9 @@ private def compileImpl(x: Expr[Dsl])(using Quotes): Expr[Option[String]] = {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
case class Foo(id: Int)
|
||||
inline def queryFooId =
|
||||
query[Foo]("foo").mapAst[Int](x =>
|
||||
Map(x, Ident("x"), Property(Ident("x"), "id"))
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue