Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions sjsonnet/src/sjsonnet/Format.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package sjsonnet

import scala.util.control.NonFatal

/**
* Minimal re-implementation of Python's `%` formatting logic, since Jsonnet's `%` formatter is
* basically "do whatever python does", with a link to:
Expand Down Expand Up @@ -273,7 +275,7 @@ object Format {
}

def format(s: String, values0: Val, pos: Position)(implicit evaluator: EvalScope): Val.Str = {
val parsed = parseFormatCached(s, evaluator.formatCache)
val parsed = parseFormatOrFail(pos)(parseFormatCached(s, evaluator.formatCache))
format(parsed, values0, pos)
}

Expand Down Expand Up @@ -558,9 +560,19 @@ object Format {

def format(leading: String, chunks: scala.Seq[(FormatSpec, String)], values0: Val, pos: Position)(
implicit evaluator: EvalScope): Val.Str = {
format(lowerParsedFormat((leading, chunks)), values0, pos)
val parsed = parseFormatOrFail(pos)(lowerParsedFormat((leading, chunks)))
format(parsed, values0, pos)
}

private def parseFormatOrFail(pos: Position)(parse: => RuntimeFormat)(implicit
evaluator: EvalErrorScope): RuntimeFormat =
try parse
catch {
case e: Error => throw e
case NonFatal(e) =>
Error.fail(e.getMessage, pos)
}

private def appendLeading(output: java.lang.StringBuilder, parsed: RuntimeFormat): Unit = {
val source = parsed.source
if (source != null) output.append(source, parsed.leadingStart, parsed.leadingEnd)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
std.format("%z", [1])
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
sjsonnet.Error: [std.format] Unrecognized conversion type: z
at [<root>].(error.format_invalid_conversion.jsonnet:1:11)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"%z" % [1]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sjsonnet.Error: Unrecognized conversion type: z
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
std.format("hello %", [])
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
sjsonnet.Error: [std.format] Truncated format code at end of string
at [<root>].(error.format_truncated.jsonnet:1:11)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
std.format("%(key", { key: "value" })
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sjsonnet.Error: [std.format] Unterminated ( in format spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
std.assertEqual(std.format("100%% done %s", ["yes"]), "100% done yes") &&
std.assertEqual(std.format("%*s", [10, "hello"]), " hello") &&
std.assertEqual(std.format("%.*f", [3, 3.14159]), "3.142") &&
std.assertEqual(std.format("%#x", [255]), "0xff") &&
true
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
true
Loading