scalaintermediate
Custom String Interpolation
Create custom string interpolators in Scala: SQL, HTML, JSON, and validated interpolation.
scalaPress ⌘/Ctrl + Shift + C to copy
// Custom string interpolators via extension on StringContext
// SQL interpolator with parameter binding
case class SqlQuery(sql: String, params: List[Any])
extension (sc: StringContext)
def sql(args: Any*): SqlQuery =
val parts = sc.parts.iterator
val params = args.iterator
val sb = StringBuilder()
val paramList = scala.collection.mutable.ListBuffer.empty[Any]
sb.append(parts.next())
while parts.hasNext do
paramList += params.next()
sb.append("?")
sb.append(parts.next())
SqlQuery(sb.toString(), paramList.toList)
// HTML interpolator with escaping
extension (sc: StringContext)
def html(args: Any*): String =
def escape(s: String): String =
s.replace("&", "&")
.replace("<", "<")
.replace(">", ">")
.replace("\"", """)
.replace("'", "'")
val parts = sc.parts.iterator
val escaped = args.iterator
val sb = StringBuilder()
sb.append(parts.next())
while parts.hasNext do
sb.append(escape(escaped.next().toString))
sb.append(parts.next())
sb.toString()
// Logging interpolator
enum LogLevel:
case DEBUG, INFO, WARN, ERROR
extension (sc: StringContext)
def log(args: Any*): (LogLevel, String) =
val msg = sc.s(args*)
val level = msg.takeWhile(_ != ':') match
case "DEBUG" => LogLevel.DEBUG
case "WARN" => LogLevel.WARN
case "ERROR" => LogLevel.ERROR
case _ => LogLevel.INFO
(level, msg)
// Regex interpolator
extension (sc: StringContext)
def r(args: Any*): scala.util.matching.Regex =
sc.s(args*).r
@main def run(): Unit =
// SQL interpolator
val name = "Alice"
val age = 30
val query = sql"SELECT * FROM users WHERE name = $name AND age > $age"
println(s"SQL: ${query.sql}")
println(s"Params: ${query.params}")
val id = 42
val update = sql"UPDATE users SET active = true WHERE id = $id"
println(s"\nUpdate SQL: ${update.sql}")
println(s"Params: ${update.params}")
// HTML interpolator (auto-escapes)
val userInput = "<script>alert('xss')</script>"
val title = "Hello & Goodbye"
val page = html"<div><h1>$title</h1><p>$userInput</p></div>"
println(s"\nHTML: $page")
// Standard interpolators
val pi = math.Pi
println(f"\nPi: $pi%.4f")
println(s"Name: $name, Age: $age")
println(raw"Newline: \n Tab: \t (raw, no escape)")
// Regex interpolator
val emailRegex = r"[a-zA-Z0-9.]+@[a-zA-Z0-9.]+"
val text = "Contact alice@test.com or bob@example.org"
val found = emailRegex.findAllIn(text).toList
println(s"\nFound emails: $found")
// Multi-line
val items = List("apple", "banana", "cherry")
val list = items.zipWithIndex.map((item, i) =>
html"<li>${i + 1}. $item</li>"
).mkString("\n")
println(s"\nList:\n$list")Use Cases
- SQL query building with parameter binding
- XSS-safe HTML generation
- Domain-specific string formatting
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
scalaadvanced
Context Functions and Capability Pattern
Use Scala 3 context functions for dependency injection, capability passing, and builder DSLs.
Best for: Dependency injection without frameworks
#scala#context-functions
scalaadvanced
DSL Builder Pattern
Create type-safe domain-specific languages with Scala's builder pattern using apply and infix notation.
Best for: Type-safe query builders
#scala#dsl
scalabeginner
Scala Hello World Application
Create a basic Scala application with main method, string interpolation, and val/var basics.
Best for: Getting started with Scala
#scala#basics
scalabeginner
Pattern Matching Fundamentals
Use Scala pattern matching with guards, type patterns, tuple patterns, and nested extractors.
Best for: Control flow with pattern matching
#scala#pattern-matching