withMapping

inline fun <T : Any> TomlDecoder.withMapping(vararg mapping: Pair<String, String>): TomlDecoder

Returns a copy of the receiver TOML decoder, extended with a custom property mapping for the type T.

Having a custom property mapping from "foo" to "bar" for some type T means that whenever the decoder (a) is decoding a table (b) into a value of type T, any constructor parameter of T with the name "bar" will receive its value from a TOML property with the name "foo".

As a motivating example, in a TOML document describing a list of users, it is natural to use the singular of "user" to add new users to the list:


[[user]]
name = 'Alice'
password = 'correcthorsebatterystaple'

[[user]]
name = 'Bob'
password = 'password1'

However, this makes less sense in the corresponding Kotlin type, where you would normally use the plural "users" as the name for a list of users:


data class User(val name: String, val password: String)
data class UserList(val users: List<User>)

A custom mapping allows us to quickly bridge this gap, without compromising on either our Kotlin naming standards or our configuration syntax:


val myDecoder = TomlDecoder.default.withMapping<UserList>("user" to "users")
val myUsers = toml.from(Path.of("path", "to", "users.toml")).decode<UserList>(myDecoder)

This also lets us rename fields in our model types while maintaining a stable configuration file syntax by simply specifying a custom mapping, all without having to add intrusive annotations to model types where they don't belong.

fun <T : Any> TomlDecoder.withMapping(kClass: KClass<T>, vararg mapping: Pair<String, String>): TomlDecoder

Returns a copy of the receiver TOML decoder, extended with a custom property mapping for the type T.