Hi. If I have an generic interface that is ment fo...
# getting-started
d
Hi. If I have an generic interface that is ment for mapping from `Enum`s to some binary form (lets say arrays of bools), can I enforce at compile-time that the map contains all the enum variants as keys (via annotations perhaps?)
Copy code
interface BinaryFlagMapper<E : Enum<E>> {
    val map: Map<E, Int> //lets say Int is index in Array of bools
...
}

val mapperForMyEnum = object : BinaryFlagMapper<MyEnum> {
    override val map = mapOf(
         // how to enforce at compile time that this contains all the entries in MyEnum as keys?
    )
}
w
To answer your question: No you can not force this. For the behavior you are describing, you might be interested in
java.util.EnumSet
if you're targeting JVM. Otherwise you might be interested in enumValues. Here is a mockup of how you could implement your interface using them:
Copy code
inline fun <reified E: Enum<E>> binaryFlagMapper(): BinaryFlagMapper<E> {
    val values = enumValues<E>()
    val flags = BooleanArray(values.size) { false }
    val map: Map<E, Int> = values.associateWith { it.ordinal }

    return object: BinaryFlagMapper<E> {
        override val map: Map<E, Int> get() = map
    }
}

val mapperForMyEnum = binaryFlagMapper<MyEnum>()
Please be aware that inline functions will be inlined into your source code at every call site. Consider keeping the inlined part as small as possible. Example would be:
Copy code
inline fun <reified E: Enum<E>> binaryFlagMapper(): BinaryFlagMapper<E> = binaryFlagMapper(enumValues<E>())
fun <E : Enum<E>> binaryFlagMapper(values: Array<E>): BinaryFlagMapper<E> {
    TODO("Big function here")
}
d
Maybe I will try to replace the map with a function that returns that value and implement it using
when
expression. That way it will cause an error if its non exhaustive 🤔
1