pebble
pebble copied to clipboard
can't use Java 11 var api with evaluate
this does not compile
var writer = new StringWriter();
var tmpl = engine.getTemplate( "TestApplication.java.pbl" );
tmpl.evaluate( writer, context ); // fails here due to map being `Map<String, String>`
probably better to make the inbound map value type generic, e.g
<T> void evaluate( Map<String, T> context ) {
}
here's the full class, if it helps
/* Copyright © 2020 Caleb Cushing. All rights reserved */
package com.xenoterracide.scaf;
import com.mitchellbosecke.pebble.PebbleEngine;
import com.mitchellbosecke.pebble.loader.FileLoader;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import picocli.CommandLine;
import java.io.StringWriter;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
@CommandLine.Command(name = "skaf")
public final class Application implements Runnable {
@Nullable
@CommandLine.Parameters(index = "0", description = "first configuration directory")
private String arg;
@CommandLine.Parameters(
index = "1..*",
description = "path to configuration directories separated by space"
)
private List<String> args = List.of();
@CommandLine.Option(names = { "-d", "--dir" }, description = "path to scaf directory")
private Path dir = Path.of(".scaf");
@CommandLine.Option(names = "--template-dir", description = "template directory")
private Path templateDir = dir.resolve("templates");
/*
@CommandLine.Option( names = "--config-dir", description = "config directory" )
private Path configDir = dir.resolve( "config" );
*/
private final FileLoader loader = new FileLoader();
private final PebbleEngine engine = new PebbleEngine.Builder()
.newLineTrimming( false )
.strictVariables( true )
.loader( loader )
.build();
@Override
public void run() {
if (arg == null) {
throw new IllegalStateException("impossible!");
}
loader.setPrefix( templateDir.toString() );
var name = args.remove( args.size() -1 );
var context = Map.of("name", name);
var writer = new StringWriter();
var tmpl = engine.getTemplate( "TestApplication.java.pbl" );
tmpl.evaluate( writer, context ); // fails here due to map being `Map<String, String>`
}
public static void main(@NonNull String... args) {
var cli = new CommandLine(new Application());
System.exit(cli.execute(args));
}
}
It is possible to tell the compiler to use it as a <String, Object> by doing Map<String, Object> context = Map.of("name", name);.
right, but couldn't PebbleTemplate.getTemplate take a generic based on the input? e.g <T> Map<String, T>.
HashMap<String, Object> context = Map.of("name", name);
is the returned a HashMap? I could check but I think it just returns Map and that Map is immutable, I think. Still I am doing Map<String, Object> here, that was my workaround, I just think if it took a generic one wouldn't have to workaround it.
Apologies, I used a Map when testing it but as I use HashMap all the time I automatically wrote it as HashMap in my answer. And your idea seems nice, maybe make a pull request? Doesn't sound too hard.