package starter.utils import com.mitchellbosecke.pebble.PebbleEngine import com.mitchellbosecke.pebble.cache.tag.CaffeineTagCache import com.mitchellbosecke.pebble.cache.tag.ConcurrentMapTagCache import com.mitchellbosecke.pebble.cache.tag.NoOpTagCache import com.mitchellbosecke.pebble.cache.template.CaffeineTemplateCache import com.mitchellbosecke.pebble.cache.template.ConcurrentMapTemplateCache import com.mitchellbosecke.pebble.cache.template.NoOpTemplateCache import com.mitchellbosecke.pebble.extension.AbstractExtension import com.mitchellbosecke.pebble.extension.Filter import com.mitchellbosecke.pebble.extension.Function import com.mitchellbosecke.pebble.loader.ClasspathLoader import java.io.StringWriter fun PebbleEngine.render(name: String, args: Map = mapOf()) = getTemplate(name).let { StringWriter().apply { it.evaluate(this, args) }.toString() } fun PebbleEngine.render(name: String, vararg args: Pair) = render(name, mapOf(*args)) interface PebbleFunction : Function { val name: String } interface PebbleFilter : Filter { val name: String } class PebbleEngineBuilder { enum class CacheType { None, Caffeine, ConcurrentMap } private var loader = ClasspathLoader() var cache = CacheType.ConcurrentMap private val functions = mutableListOf() private val filters = mutableListOf() fun function(function: PebbleFunction) { functions.add(function) } fun functions(functions: Iterable) { this.functions.addAll(functions) } fun filter(filter: PebbleFilter) { filters.add(filter) } fun filters(filters: Iterable) { this.filters.addAll(filters) } fun classPath(block: ClasspathLoader.() -> Unit) { loader = ClasspathLoader().apply(block) } companion object { operator fun invoke(block: PebbleEngineBuilder.() -> Unit): PebbleEngine = PebbleEngineBuilder().apply(block).let { builder -> PebbleEngine.Builder() .loader(builder.loader) .cacheActive(builder.cache != CacheType.None) .templateCache(when (builder.cache) { CacheType.None -> NoOpTemplateCache() CacheType.Caffeine -> CaffeineTemplateCache() CacheType.ConcurrentMap -> ConcurrentMapTemplateCache() }) .tagCache(when (builder.cache) { CacheType.None -> NoOpTagCache() CacheType.Caffeine -> CaffeineTagCache() CacheType.ConcurrentMap -> ConcurrentMapTagCache() }) .extension(object : AbstractExtension() { override fun getFunctions(): Map? = builder.functions.associateBy { it.name }.ifEmpty { null } override fun getFilters(): Map? = builder.filters.associateBy { it.name }.ifEmpty { null } }) .build() } } }