Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Add support for lenses generation for value classes #941

@Lysander

Description

@Lysander

Motivation

Good domain modelling requires the use of value classes. Those are currently not supported by our automatic lenses generator. So there is a mismatch between good practises and the ease of our framework.

Look at this example:

@JvmInline
value class Name(val value: String) 

@JvmInline
value class Year(val value: Int) 

@Lenses
data class Person(val name: Name, val yearOfBirth: Year) {
    companion object
}

As we can only annotate the data class, we can only map the root-store as follows:

val storedPerson = storeOf(Person(Name("Chris"), Year(1978)))

val storedName: Store<Name> = storedPerson.map(Person.name())

In order to bind such a mapped store to some kind of UI element like an input, we need to access the value of the Name-type:

inputText {
    // wont work! we nned some `String` and no other type!
    value(storedName.data)

    // we need something loíke this:
    value(storedName.map(lensOf(
        "",
        getter = { v -> v.value },
        setter = { _, v -> Name(v) }
    )))
}

As this is rather clumsy, we should enhance our generator to support value classes!

Proposal

We could easily extend the @Lenses-annotation to support value classes like that:

@Lenses
@JvmInline
value class Year(val value: Int) {
    companion object 
}

@Lenses
@JvmInline
value class Name(val value: String) {
    companion object 
}

// within the `generated` section

fun Year.Companion.value(): Lens<Year, Int> = lensOf(
     "",
     getter = { p: Year -> p.value },
     setter = { _: Year, v: Int -> Year(v) }
 )

// we could specifically support the formatting `lensOf`-factory if the target type is `String`:
fun Name.companion.value(): Lens<Name, String> = lensOf(
    format = { p: Name -> p.value },
    parse = { v: String -> Name(v) },
)

Metadata

Metadata

Assignees

No one assigned

    Labels

    discussionExtra attention is needed

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions