casid / jte

Secure and speedy templates for Java and Kotlin.
https://jte.gg
Apache License 2.0
819 stars 59 forks source link

Pattern Matching with `kte` #277

Closed don41382 closed 1 year ago

don41382 commented 1 year ago

I would like to use pattern matching inside of a .kte template like shown in the documentation:

@if (model instanceof SubModel subModel)
    ${subModel.getSpecial()}
@endif

I have the following class:

data class FormField(
    val value: String,
    val error: FormError,
)

sealed interface FormError {
    object Initial : FormError
    object Ok : FormError
    data class Error(val message: String) : FormError
}

and would like to use it in my template, if there is an error:

  @if (field.error instanceof FormError.Error(msg))
            <div class="invalid-feedback">
                ${msg}
            </div>
        @endif

But that doesn't work. What am I doing wrong?

casid commented 1 year ago

@don41382 welcome!

I'm not a Kotlin user. I've only tried pattern matching with Java, where it works fine.

Do you receive a compile time error, an IDE error, or is the code compiling, but not doing anything?

don41382 commented 1 year ago

Thanks @casid for the warm welcome.

I think instanceof does not exists in Kotlin. It's done by the is statement. So changed it to:

@if (field.error is FormError.Error)
    <div class="invalid-feedback">
        ${field.error.message}
    </div>
@endif

The if statement works, but the access on the .message does not:

Reason: Smart cast to 'FormError.Error' is impossible, because 'field.error' is a complex expression

Normally you would do something like this in Kotlin:

when (formError) {
          is FormError.Error ->
              formError.message

which allows you to access the field message, but that does not to seem to work inside of .kte. It would be nice, if jte would support when, but I don't know if that would be possible.

casid commented 1 year ago

I'm not sure either, since keywords are kept as simple as possible and are the same for java / kotlin. It would be nice if Kotlin would support pattern matching in if statements, too :-)