Skip to content

Instantly share code, notes, and snippets.

@assafi
Last active December 20, 2015 05:49
Show Gist options
  • Save assafi/6081291 to your computer and use it in GitHub Desktop.
Save assafi/6081291 to your computer and use it in GitHub Desktop.
Check file name correctness during compilation using Scala interpolation / macros.
package utils
import scala.language.experimental.macros
import scala.reflect.macros.Context
object FileNameImpl {
def fileImpl(c: Context)(): c.Expr[String] = {
import c.universe._
val Apply(_, List(Apply(_, List(Literal(Constant(fileName: String)))))) = c.prefix.tree
fileName match {
case validFileName() =>
c.Expr[String](Literal(Constant(fileName)))
case _ =>
c.error(c.enclosingPosition,"string does not confirms to file name regex ^[a-zA-Z0-9._ -]+$")
c.Expr[String](Literal(Constant("")))
}
}
lazy val validFileName = """^[a-zA-Z0-9._ -]+$""".r
}
// Now, instead of accidentally writing:
val myFile = new File("some_file_with)underscores")
// You can write:
import utils.Utils
scala> val myFile = new File(file"some_file_with)underscores") // You will get a compile-time error here
//<console>:11: error: string does not confirms to file name regex ^[a-zA-Z0-9._ -]+$
// val myFile = new File(file"some_file_with)underscores")
//But this will work fine:
scala> val myFile = new File(file"some_file_with_underscores")
myFile: java.io.File = some_file_with_underscores
package utils
import scala.language.experimental.macros
object Utils {
/**
* This will allow you to write file"some_file_name" which will be evaluated at compile time!
*/
implicit class FileNameContext(val sc: StringContext) extends AnyVal {
def file():String = macro FileNameImpl.fileImpl
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment