diff options
-rw-r--r-- | .gitignore | 12 | ||||
-rw-r--r-- | build.sc | 10 | ||||
-rw-r--r-- | cask/src/cask/Cask.scala | 41 | ||||
-rw-r--r-- | cask/test/src/test/cask/CaskTest.scala | 34 |
4 files changed, 97 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8d3ee55 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +target/ +*.iml +.idea +.settings +.classpath +.project +.cache +.sbtserver +project/.sbtserver +tags +nohup.out +out diff --git a/build.sc b/build.sc new file mode 100644 index 0000000..2a3ca2c --- /dev/null +++ b/build.sc @@ -0,0 +1,10 @@ +import mill._, scalalib._ + +object cask extends ScalaModule{ + def scalaVersion = "2.12.6" + def ivyDeps = Agg(ivy"org.scala-lang:scala-reflect:$scalaVersion") + object test extends Tests{ + def ivyDeps = Agg(ivy"com.lihaoyi::utest::0.6.3") + def testFrameworks = Seq("utest.runner.Framework") + } +} diff --git a/cask/src/cask/Cask.scala b/cask/src/cask/Cask.scala new file mode 100644 index 0000000..c903cc2 --- /dev/null +++ b/cask/src/cask/Cask.scala @@ -0,0 +1,41 @@ +package cask +import language.experimental.macros +import scala.annotation.StaticAnnotation +import scala.reflect.macros.blackbox.Context +class route(val path: String) extends StaticAnnotation + +class Main(x: Any*) + +object Server{ + case class Route(name: String, metadata: route) + case class Routes[T](value: Route*) + object Routes{ + implicit def initialize[T] = macro initializeImpl[T] + implicit def initializeImpl[T: c.WeakTypeTag](c: Context): c.Expr[Routes[T]] = { + import c.universe._ + + val routes = c.weakTypeOf[T].members + .map(m => (m, m.annotations.filter(_.tree.tpe =:= c.weakTypeOf[route]))) + .collect{case (m, Seq(a)) => (m, a)} + + val routeParts = for((m, a) <- routes) yield { + val annotation = q"new ${a.tree.tpe}(..${a.tree.children.tail})" + q"cask.Server.Route(${m.name.toString}, $annotation)" + } + c.Expr[Routes[T]](q"""cask.Server.Routes(..$routeParts)""") + } + } +} + +class Server[T](){ + private[this] var routes0: Server.Routes[this.type] = null + def routes = + if (routes0 != null) routes0 + else throw new Exception("Routes not yet initialize") + + protected[this] def initialize()(implicit routes: Server.Routes[this.type]): Unit = { + routes0 = routes + } +} + + diff --git a/cask/test/src/test/cask/CaskTest.scala b/cask/test/src/test/cask/CaskTest.scala new file mode 100644 index 0000000..a1384f8 --- /dev/null +++ b/cask/test/src/test/cask/CaskTest.scala @@ -0,0 +1,34 @@ +package test.cask + + +object MyServer extends cask.Server(){ + + def x = "/ext" + @cask.route("/user/:username" + (x * 2)) + def showUserProfile(userName: String) = { + // show the user profile for that user + s"User $userName" + } + + @cask.route("/post/:int") + def showPost(postId: Int) = { + // show the post with the given id, the id is an integer + s"Post $postId" + } + + @cask.route("/path/:subPath") + def show_subpath(subPath: String) = { + // show the subpath after /path/ + s"Subpath $subPath" + } + + initialize() + println(routes.value) +} + +object Main extends cask.Main(MyServer){ + def main(args: Array[String]): Unit = { + MyServer + } +} + |