I have an object with some optional attributes which I want to list in a string template (In a sort of JSON way) If the attribute is None I don’t want to see anything, if it is Non None I want to see a label with the value:
case class FooTest(a: String, b: Option[String], c: String)
val test = FooTest("one", Some("two"), "three");
val myTemplate = s"""
| "een" : "${test.a}"
| ${test.b.fold(""){tb => s""twee": "$tb"}
| "drie" : "${test.c}"
"""
This works expected with Some("value")
for test.b
, but it leaves a blank line for
None
for test.b
:
"een" : "one"
"drie" : "three"
How can I get rid of the empty line (apart from replacing 2 subsequent newline characters with 1 newline in the resulting string)?
2
One possibility might be to inline the second line and explicitly add the newline, which kinda works but doesn’t interact too nicely with indentation:
case class FooTest(a: String, b: Option[String], c: String)
def template(test: FooTest) = s"""
| "een" : "${test.a}"${test.b.fold(""){tb => s"n"twee": "$tb""}}
| "drie" : "${test.c}"
""".stripMargin
println(template(FooTest("one", Some("two"), "three")))
println(template(FooTest("one", None, "three")))
Output:
"een" : "one"
"twee": "two"
"drie" : "three"
"een" : "one"
"drie" : "three"
If you want to keep the template string nice and work well with the template indentation, one possible approach is to remove the empty lines in a second pass, as follows:
case class FooTest(a: String, b: Option[String], c: String)
def template(test: FooTest) = s"""
| "een" : "${test.a}"
| ${test.b.fold(""){tb => s""twee": "$tb""}}
| "drie" : "${test.c}"
""".stripMargin
def deleteEmptyLines(s: String) = s.replaceAll("\n\s*\n", "n")
println(deleteEmptyLines(template(FooTest("one", Some("two"), "three"))))
println(deleteEmptyLines(template(FooTest("one", None, "three"))))
Output:
"een" : "one"
"twee": "two"
"drie" : "three"
"een" : "one"
"drie" : "three"
You can play around with this code here on Scastie.