Skip to content

Commit

Permalink
Add support for conditions and loops to CodeWriter
Browse files Browse the repository at this point in the history
CodeWriter now supports Mustache-like behavior by allowing conditions
and loops to be evaluated in templates. Note that this does disallow
using '/', '?', '^', and '#' as formatters.

Conditions are defined using `${?foo}` where "foo" is the writer named
parameter to evaluate. `?` is used to check if a value is truthy.

The following template with a "foo" value set to "Noid":

```
${?foo}
Hello, ${foo:L}!
${/foo}
```

Evaluates to:

```
Hello, Noid!
```

`^` can be used to check if a value is falsey. The following template
with no set "baz" value:

```
${baz}
  Yes baz
${/baz}
${^baz}
  No baz
${/baz}
```

Evaluates to:

```
  No baz
```

A variable is falsey if it is Boolean false, an empty Iterable, an empty
Optional, an empty Map, or an empty String. A variable is truthy if it
is not falsey.

If a conditional expression or loop expression is the non-whitespace
text on a line and is immediately followed by a `\r` or `\n`, then the
entire line is omitted from the output.

Loops can be created using `${#foo}`. Each value contained in the
referenced named parameter is sent through the contained templated one
after the other.

The following template with a "foo" value of ["a", "b"]:

```
${#foo}
- ${currentKey:L}: ${currentValue:L}
${/foo}
```

Evaluates to:

```
- 0: a
- 1: b
```

Each iteration of the loop creates a new state in the writer that sets a
named parameter named `currentKey` that contains the current index of
the loop or the current key of a map entry; `currentValue` containing
the current value of the iterable or current value of a map entry;
`currentIsFirst` is set to true when the first value is being evaluated,
and `currentIsLast` is set to true when the last value is being evaluated.

```
SimpleCodeWriter writer = new SimpleCodeWriter()
        .trimTrailingSpaces(false)
        .insertTrailingNewline(false);
writer.putContext("foo", Arrays.asList("a", "b", "c"));
writer.write("""
        ${#foo}
        ${?currentIsFirst}
        [
        ${/currentIsFirst}
            ${currentValue:L}${^currentIsLast},${/currentIsLast}
        ${?currentIsLast}
        ]
        ${/currentIsLast}
        ${/foo}""");

assertThat(writer.toString(), equalTo("""
        [
            a,
            b,
            c
        ]
        """);
```
  • Loading branch information
mtdowling committed Mar 21, 2022
1 parent 4a1ec3a commit 9d78b3a
Show file tree
Hide file tree
Showing 2 changed files with 620 additions and 72 deletions.
Loading

0 comments on commit 9d78b3a

Please sign in to comment.