Skip to content

Commit

Permalink
Merge pull request #1098 from japgolly/custom-routes
Browse files Browse the repository at this point in the history
Allow custom route parsers
  • Loading branch information
rpiaggio authored Dec 12, 2024
2 parents a1aa1bb + 83ad0d1 commit c6fad3b
Show file tree
Hide file tree
Showing 11 changed files with 194 additions and 40 deletions.
3 changes: 3 additions & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
use flake
layout node
eval "$shellHook"
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ metals.sbt
node_modules/
package-lock.json
target
.direnv/
2 changes: 1 addition & 1 deletion downstream-tests/scalafix.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ ThisBuild / scalacOptions ++= {

ThisBuild / semanticdbEnabled := true

ThisBuild / semanticdbVersion := "4.5.9"
ThisBuild / semanticdbVersion := "4.12.0"

ThisBuild / scalafixScalaBinaryVersion := "2.13"

Expand Down
109 changes: 109 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 43 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
inputs = {
typelevel-nix.url = "github:typelevel/typelevel-nix";
nixpkgs.follows = "typelevel-nix/nixpkgs";
flake-utils.follows = "typelevel-nix/flake-utils";
};

outputs = { self, nixpkgs, flake-utils, typelevel-nix }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs-x86_64 = import nixpkgs { system = "x86_64-darwin"; };
scala-cli-overlay = final: prev: { scala-cli = pkgs-x86_64.scala-cli; };
pkgs = import nixpkgs {
inherit system;
overlays = [ typelevel-nix.overlays.default scala-cli-overlay];
};
in
{
devShell = pkgs.devshell.mkShell {
imports = [ typelevel-nix.typelevelShell ];
packages = [
pkgs.nodePackages.typescript-language-server
pkgs.nodePackages.vscode-langservers-extracted
pkgs.nodePackages.prettier
pkgs.nodePackages.typescript
pkgs.nodePackages.graphqurl
pkgs.hasura-cli
];
typelevelShell = {
nodejs.enable = true;
jdk.package = pkgs.jdk11;
};
env = [
{
name = "NODE_OPTIONS";
value = "--max-old-space-size=8192";
}
];
};
}

);
}
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ final class CallbackOption[+A](val underlyingRepr: CallbackOption.UnderlyingRepr
def asCallback: CallbackTo[Option[A]] =
CallbackTo lift cbfn

inline def map[B](f: A => B)(using inline ev: MapGuard[B]): CallbackOption[ev.Out] =
inline def map[B](f: A => B)(using ev: MapGuard[B]): CallbackOption[ev.Out] =
unsafeMap(f)

private[react] def unsafeMap[B](f: A => B): CallbackOption[B] =
Expand All @@ -192,7 +192,7 @@ final class CallbackOption[+A](val underlyingRepr: CallbackOption.UnderlyingRepr
/**
* Alias for `map`.
*/
inline def |>[B](f: A => B)(using inline ev: MapGuard[B]): CallbackOption[ev.Out] =
inline def |>[B](f: A => B)(using ev: MapGuard[B]): CallbackOption[ev.Out] =
map(f)

def flatMapOption[B](f: A => Option[B]): CallbackOption[B] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,11 +306,11 @@ final class CallbackTo[+A] /*private[react]*/ (private[CallbackTo] val trampolin
inline def runNow(): A =
trampoline.run

inline def map[B](f: A => B)(using inline ev: MapGuard[B]): CallbackTo[ev.Out] =
inline def map[B](f: A => B)(using ev: MapGuard[B]): CallbackTo[ev.Out] =
new CallbackTo(trampoline.map(f))

/** Alias for `map`. */
inline def |>[B](inline f: A => B)(using inline ev: MapGuard[B]): CallbackTo[ev.Out] =
inline def |>[B](inline f: A => B)(using ev: MapGuard[B]): CallbackTo[ev.Out] =
map(f)

inline def flatMap[B](f: A => CallbackTo[B]): CallbackTo[B] =
Expand Down Expand Up @@ -589,7 +589,7 @@ final class CallbackTo[+A] /*private[react]*/ (private[CallbackTo] val trampolin


/** Convenience-method to run additional code after this callback. */
inline def thenRun[B](inline runNext: B)(using inline ev: MapGuard[B]): CallbackTo[ev.Out] =
inline def thenRun[B](inline runNext: B)(using ev: MapGuard[B]): CallbackTo[ev.Out] =
this >> CallbackTo(runNext)

/** Convenience-method to run additional code before this callback. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ object StaticDsl {
val / = literal("/")
}

abstract class RouteCommon[R[X] <: RouteCommon[R, X], A] {
trait RouteCommon[R[X] <: RouteCommon[R, X], A] {

def parseThen(f: Option[A] => Option[A]): R[A]

Expand Down Expand Up @@ -159,7 +159,7 @@ object StaticDsl {
// val g = p.matcher("").groupCount
// if (g != matchGroups)
// sys.error(s"Error in regex: /${p.pattern}/. Expected $matchGroups match groups but detected $g.")
new Route(p, m => parse(i => m.group(i + 1)), a => Path(build(a)))
Route.forPattern(p, m => parse(i => m.group(i + 1)), a => Path(build(a)))
}
}

Expand Down Expand Up @@ -192,30 +192,28 @@ object StaticDsl {
}

/**
* A complete route.
* A `Route` translates a `Path` into an instance of model `A` and vice versa.
*/
final class Route[A](pattern: Pattern,
parseFn: Matcher => Option[A],
buildFn: A => Path) extends RouteCommon[Route, A] with RouterMacros.ForRoute[A] {
override def toString =
s"Route($pattern)"

case class Route[A](parse: Path => Option[A], pathFor: A => Path) extends RouteCommon[Route, A] {
override def parseThen(f: Option[A] => Option[A]): Route[A] =
new Route(pattern, f compose parseFn, buildFn)
Route(f compose parse, pathFor)

override def pmap[B](b: A => Option[B])(a: B => A): Route[B] =
new Route(pattern, parseFn(_) flatMap b, buildFn compose a)

def parse(path: Path): Option[A] = {
val m = pattern.matcher(path.value)
if (m.matches)
parseFn(m)
else
None
}
Route(parse(_) flatMap b, pathFor compose a)
}

def pathFor(a: A): Path =
buildFn(a)
object Route {
def forPattern[A](pattern: Pattern, parseFn: Matcher => Option[A], buildFn: A => Path): Route[A] =
new Route(
p => {
val m = pattern.matcher(p.value)
if (m.matches)
parseFn(m)
else
None
},
buildFn
)
}

// ===================================================================================================================
Expand Down
20 changes: 10 additions & 10 deletions library/project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,23 @@ object Dependencies {
object Ver {

// Externally observable
val cats = "2.7.0"
val catsEffect = "3.3.11"
val microlibs = "4.2.1"
val cats = "2.12.0"
val catsEffect = "3.5.4"
val microlibs = "4.1.0"
val monocle2 = "2.1.0"
val monocle3 = "3.1.0"
val scala2 = "2.13.8"
val scala3 = "3.1.2"
val scalaJsDom = "2.0.0"
val sourcecode = "0.2.8"
val monocle3 = "3.2.0"
val scala2 = "2.13.15"
val scala3 = "3.3.0"
val scalaJsDom = "2.8.0"
val sourcecode = "0.4.2"

// Internal
val betterMonadicFor = "0.3.1"
val catsTestkitScalaTest = "2.1.5"
val disciplineScalaTest = "2.1.5"
val fastTextEncoding = "1.0.6"
val kindProjector = "0.13.2"
val macrotaskExecutor = "1.0.0"
val kindProjector = "0.13.3"
val macrotaskExecutor = "1.1.1"
val nyaya = "1.0.0"
val reactJs = "18.2.0"
val scalaJsJavaTime = "1.0.0"
Expand Down
4 changes: 2 additions & 2 deletions library/project/plugins.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ libraryDependencies ++= Seq(
"org.scala-js" %% "scalajs-env-jsdom-nodejs" % "1.1.0",
"org.scala-js" %% "scalajs-env-selenium" % "1.1.1")

addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.10.1")
addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.5.10")
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.12.1")
addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.5.12")
addSbtPlugin("org.scala-js" % "sbt-jsdependencies" % "1.0.2")
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.16.0")
2 changes: 1 addition & 1 deletion library/scalafix.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ ThisBuild / scalacOptions ++= {
ThisBuild / semanticdbEnabled := true

// NOTE: Upgrade downstream-tests/scalafix.sbt too!
ThisBuild / semanticdbVersion := "4.5.9"
ThisBuild / semanticdbVersion := "4.12.0"

0 comments on commit c6fad3b

Please sign in to comment.