stone-macros


License

License

GroupId

GroupId

ba.sake
ArtifactId

ArtifactId

stone-macros_2.12
Last Version

Last Version

0.1.0
Release Date

Release Date

Type

Type

jar
Description

Description

stone-macros
stone-macros
Project URL

Project URL

https://github.com/sake92/stone
Project Organization

Project Organization

ba.sake
Source Code Management

Source Code Management

https://github.com/sake92/stone

Download stone-macros_2.12

How to add to project

<!-- https://jarcasting.com/artifacts/ba.sake/stone-macros_2.12/ -->
<dependency>
    <groupId>ba.sake</groupId>
    <artifactId>stone-macros_2.12</artifactId>
    <version>0.1.0</version>
</dependency>
// https://jarcasting.com/artifacts/ba.sake/stone-macros_2.12/
implementation 'ba.sake:stone-macros_2.12:0.1.0'
// https://jarcasting.com/artifacts/ba.sake/stone-macros_2.12/
implementation ("ba.sake:stone-macros_2.12:0.1.0")
'ba.sake:stone-macros_2.12:jar:0.1.0'
<dependency org="ba.sake" name="stone-macros_2.12" rev="0.1.0">
  <artifact name="stone-macros_2.12" type="jar" />
</dependency>
@Grapes(
@Grab(group='ba.sake', module='stone-macros_2.12', version='0.1.0')
)
libraryDependencies += "ba.sake" % "stone-macros_2.12" % "0.1.0"
[ba.sake/stone-macros_2.12 "0.1.0"]

Dependencies

compile (2)

Group / Artifact Type Version
org.scala-lang : scala-library jar 2.12.8
org.scala-lang : scala-reflect jar 2.12.8

Project Modules

There are no modules declared in this project.

Stone Maven Central Build Status

Handy Scala macros for everyday use: Route, Wither.

Scala 2.13 only!
ScalaJS 1 is supported.

@Route

Generates apply/unapply methods for extracting/constructing URLs. Here's why:

  • type safe URLs/routes
  • unlike Play SIRD and others, it can also construct a URL

In Play, Angular and other frameworks you'd write something like this:
/users/:id/:name ? minAge=:minAge & qs=:qs...

With @Route macro you write this:

@Route
class UsersRoute( /* first list contains path params */
    p1: "users",      // fixed
    val id: Long,     // variable
    val name: String
)(                /* second list contains query params (those after ?) */
    val minAge: Int,      // mandatory
    val opt: Option[Int], // optional
    val qs: Set[String]   // multi-valued
)

// construct a URL, type-safely
val route = UsersRoute(1, "Sake")(123, Some(456), Set("q1"))
val redirectUrl = route.urlData.url // /users/1/Sake?minAge=18&opt=456&qs=q1

// deconstruct a string URL to type-safe data
"users/1/Sake?minAge=123&qs=q1&qs=q2&opt=456" match {
  case UsersRoute(id, name, minAge, opt, qs) =>
    println(s"$id, $name, $minAge, $opt, $qs") // 1, Sake, 123, Some(456), Set(q1, q2)
  case _ => println("404 Not Found")
}

Match path segment regex

Regex is supported, just put it inside angle brackets:

@Route class RegexRoute(p1: "users", val name: "<[a-z]+>")

This would match a string /users/tom, but not /users/Tom.

Match multiple path segments

You can match on multi-segment path with a *:

@Route class StarRoute(p1: "files", val path: "*")

This would match a string /files/images/abc.jpg etc.
Basically, anything starting with /files...


@Wither

Generates with* methods. Here's why:

  • more readable than named args
  • autocomplete is nicer
  • additional withers for Option, List etc

If you have this:

@Wither
class MyClass(
  simple: Int,
  opt: Option[Int],
  list: List[Int]
)

you get to write:

val data = new ExampleData(1, Some(10), List(100))

data.withSimple(2)            // MyClass(2, Some(10), List(100))

data.withOpt(Some(11))        // MyClass(2, Some(11), List(100))
data.withOpt(12)              // MyClass(2, Some(12), List(100))

data.withList(List(101, 102)) // MyClass(7, None, List(101,102))
data.withList(103, 104)       // MyClass(7, None, List(103,104))

data.withSimple(2).withOpt(12).withList(103, 104) // MyClass(2, Some(12), List(103,104))

Versions

Version
0.1.0
0.0.3
0.0.2