summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2018-07-20 08:48:05 +0800
committerLi Haoyi <haoyi.sg@gmail.com>2018-07-20 08:48:05 +0800
commit37bfff46d2d875d2dec27a24973ec8f6784f1bfb (patch)
treef2d13a4d13bdc9b0a7bddaf6ab6b31e6debe60a2
downloadcask-37bfff46d2d875d2dec27a24973ec8f6784f1bfb.tar.gz
cask-37bfff46d2d875d2dec27a24973ec8f6784f1bfb.tar.bz2
cask-37bfff46d2d875d2dec27a24973ec8f6784f1bfb.zip
first commit
-rw-r--r--.gitignore12
-rw-r--r--build.sc10
-rw-r--r--cask/src/cask/Cask.scala41
-rw-r--r--cask/test/src/test/cask/CaskTest.scala34
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
+ }
+}
+