From f4b2933cfb4baee313fd6ab3be87b2e312ec42e3 Mon Sep 17 00:00:00 2001 From: Tim Nieradzik Date: Fri, 1 Mar 2019 19:41:32 +0100 Subject: [PATCH] Add Scala Native support Modelled after [toml-scala](https://github.com/sparsetech/toml-scala). Closes #20. --- .travis.yml | 31 ++++++++++++++--- README.md | 2 +- build.sbt | 33 ++++++++++++------ manual/introduction.md | 4 +-- native/src/main/scala/trail/URI.scala | 48 +++++++++++++++++++++++++++ project/build.properties | 2 +- project/plugins.sbt | 6 ++-- 7 files changed, 105 insertions(+), 21 deletions(-) create mode 100644 native/src/main/scala/trail/URI.scala diff --git a/.travis.yml b/.travis.yml index 7a957f5..0865c89 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,29 @@ -language: scala -scala: - - 2.11.12 - - 2.12.8 +language: java +env: + - TRAVIS_SCALA_VERSION=2.11.11 + - TRAVIS_SCALA_VERSION=2.12.8 jdk: - oraclejdk8 + +dist: trusty +sudo: required + +addons: + apt: + update: true + +# Cache directory to S3 at the end of the build +cache: + directories: + - $HOME/.cache/coursier + +# From https://raw.githubusercontent.com/scalalandio/chimney/master/.travis.yml +before_script: + - if [[ "$TRAVIS_SCALA_VERSION" == 2.11.* ]]; then curl https://raw.githubusercontent.com/scala-native/scala-native/master/scripts/travis_setup.sh | bash -x; fi + script: - sbt ++$TRAVIS_SCALA_VERSION trailJS/test trailJVM/test + - set -x && + if [[ "$TRAVIS_SCALA_VERSION" == 2.11.* ]]; then testNative=trailNative/test; else testNative=""; fi && + curl -o csbt https://raw.githubusercontent.com/coursier/sbt-launcher/master/csbt && + chmod +x csbt && + ./csbt --add-coursier=true ++$TRAVIS_SCALA_VERSION trailJVM/test trailJS/test $testNative diff --git a/README.md b/README.md index 9c32d43..a140ef5 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Join the chat at https://gitter.im/sparsetech/trail](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/sparsetech/trail?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Maven Central](https://img.shields.io/maven-central/v/tech.sparse/trail_2.12.svg)](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22tech.sparse%22%20AND%20a%3A%22trail_2.12%22) -Trail is a routing library for Scala and Scala.js. +Trail is a routing library for Scala. It is available for the JVM, Scala.js and Scala Native. ## Example ```scala diff --git a/build.sbt b/build.sbt index 9893e6a..b609667 100644 --- a/build.sbt +++ b/build.sbt @@ -5,17 +5,20 @@ val Leaf = "0.1.0" val Scala2_11 = "2.11.12" val Scala2_12 = "2.12.8" val ScalaTest = "3.0.5" +val ScalaTestNative = "3.2.0-SNAP10" val SharedSettings = Seq( - name := "trail", + name := "trail", organization := "tech.sparse", - scalaVersion := Scala2_12, + + scalaVersion := Scala2_12, crossScalaVersions := Seq(Scala2_12, Scala2_11), - scalacOptions := Seq( + scalacOptions := Seq( "-unchecked", "-deprecation", "-encoding", "utf8" ), + pomExtra := https://github.com/sparsetech/trail @@ -36,20 +39,30 @@ val SharedSettings = Seq( ) -lazy val trail = crossProject(JSPlatform, JVMPlatform) - .crossType(CrossType.Full) +lazy val root = project.in(file(".")) + .aggregate(trail.js, trail.jvm, trail.native) + .settings(SharedSettings: _*) + .settings(skip in publish := true) + +lazy val trail = crossProject(JSPlatform, JVMPlatform, NativePlatform) .in(file(".")) .settings(SharedSettings: _*) .settings( autoAPIMappings := true, apiMappings += (scalaInstance.value.libraryJar -> url(s"http://www.scala-lang.org/api/${scalaVersion.value}/")), - libraryDependencies ++= Seq( - "org.scalatest" %%% "scalatest" % ScalaTest % "test" - ) ) .jsSettings( - /* Use io.js for faster compilation of test cases */ - scalaJSStage in Global := FastOptStage + libraryDependencies += "org.scalatest" %%% "scalatest" % ScalaTest % "test" + ) + .jvmSettings( + libraryDependencies += "org.scalatest" %%% "scalatest" % ScalaTest % "test" + ).nativeSettings( + scalaVersion := Scala2_11, + crossScalaVersions := Seq(Scala2_11), + // See https://github.com/scalalandio/chimney/issues/78#issuecomment-419705142 + nativeLinkStubs := true, + libraryDependencies += + "org.scalatest" %%% "scalatest" % ScalaTestNative % "test" ) lazy val manual = project.in(file("manual")) diff --git a/manual/introduction.md b/manual/introduction.md index 2ff5ad5..b3a8a97 100644 --- a/manual/introduction.md +++ b/manual/introduction.md @@ -1,12 +1,12 @@ # Introduction -Trail is a routing library for Scala and Scala.js. It allows to define type-safe routes, generate URLs and perform pattern matching. +Trail is a routing library for Scala. It allows to define type-safe routes, generate URLs and perform pattern matching. ## Installation Add the following dependencies to your build configuration: ```scala libraryDependencies += "tech.sparse" %% "trail" % "%version%" // Scala -libraryDependencies += "tech.sparse" %%% "trail" % "%version%" // Scala.js +libraryDependencies += "tech.sparse" %%% "trail" % "%version%" // Scala.js, Scala Native ``` ## Example diff --git a/native/src/main/scala/trail/URI.scala b/native/src/main/scala/trail/URI.scala new file mode 100644 index 0000000..496bf40 --- /dev/null +++ b/native/src/main/scala/trail/URI.scala @@ -0,0 +1,48 @@ +package trail + +import java.net.URLEncoder +import java.io.ByteArrayOutputStream + +object URI { + /** @see http://stackoverflow.com/questions/607176/ */ + def encode(s: String): String = + URLEncoder.encode(s, "UTF-8") + .replaceAll("\\+", "%20") + .replaceAll("\\%21", "!") + .replaceAll("\\%27", "'") + .replaceAll("\\%28", "(") + .replaceAll("\\%29", ")") + .replaceAll("\\%7E", "~") + + /** Taken from https://android.googlesource.com/platform/libcore/+/adc854b798c1cfe3bfd4c27d68d5cee38ca617da/luni/src/main/java/java/net/URLDecoder.java */ + def decode(s: String): String = { + val result = new StringBuffer(s.length) + val out = new ByteArrayOutputStream + var i = 0 + + while (i < s.length) { + val c = s.charAt(i) + if (c == '+') result.append(' ') + else if (c == '%') { + out.reset() + do { + if (i + 2 >= s.length) + throw new IllegalArgumentException("Incomplete % sequence at: " + i) + val d1 = Character.digit(s.charAt(i + 1), 16) + val d2 = Character.digit(s.charAt(i + 2), 16) + if (d1 == -1 || d2 == -1) + throw new IllegalArgumentException( + s"Invalid % sequence (${s.substring(i, i + 3)}) at: ${String.valueOf(i)}.") + out.write(((d1 << 4) + d2).toByte) + i += 3 + } while (i < s.length && s.charAt(i) == '%') + result.append(out.toString("UTF-8")) + } else { + result.append(c) + i += 1 + } + } + + result.toString + } +} diff --git a/project/build.properties b/project/build.properties index 7c58a83..c0bab04 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.2.6 +sbt.version=1.2.8 diff --git a/project/plugins.sbt b/project/plugins.sbt index 13f02eb..05049e4 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,6 @@ logLevel := Level.Warn -addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "0.6.0") -addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.26") +addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "0.6.0") +addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "0.6.0") +addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.26") +addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.3.8")