diff --git a/.travis.yml b/.travis.yml
index 7a957f5..aa43c6d 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 -L -o csbt https://github.com/coursier/sbt-launcher/releases/download/v1.2.2/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..83a2f9e 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,17 @@
[![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.
+
+## Features
+* Define type-safe routes
+* Parse and generate URLs
+* DSL to extract path elements, arguments and fragments
+* Express routing tables via pattern matching
+* Define custom codecs
+* IDE support
+* Cross-platform support (JVM, Scala.js, Scala Native)
+* Zero dependencies
## 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..d470f08 100644
--- a/manual/introduction.md
+++ b/manual/introduction.md
@@ -1,15 +1,15 @@
# 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
+## Usage
Create a route:
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")