Compound
A Compound
is a key-value store that serializes its data using the registered serializers.
Data is deserialized lazily. This means that until you specifically request a value, it will be stored as binary data (It will of course be cached after the first time it is requested).
Basic usage
val compound = Compound()
compound["test1"] = 123
compound["test2"] = "test"
compound["test3"] = true
compound["test4"] = mapOf("test" to 123, "test2" to 321)
compound["test5"] = Compound().apply { this["list"] = listOf(123, 321) }
This will create a compound with the following data:
{
"test1": 123
"test2": test
"test3": true
"test4": {test=123, test2=321}
"test5": {
"list": [123, 321]
}
}
We can serialize it the same way we serialize any other object:
We can then deserialize it, and get back the same data:
val compound = Cbf.read<Compound>(bytes)!!
println(compound.get<Int>("test1")) // prints 123
println(compound.get<String>("test2")) // prints test
println(compound.get<Boolean>("test3")) // prints true
println(compound.get<Map<String, Int>>("test4")) // prints {test=123, test2=321}
println(compound.get<Compound>("test5")!!.get<List<Int>>("list")) // prints [123, 321]
Entry providers
Using Compound.entry<T>(key: String)
, you can obtain a
MutableProvider<T?>
that will contain the value of type T
under the given key.
Non-defaulting
Non-defaulting entry providers will contain null
if there is no value under the given key.
Changing the value of the provider updates the value stored inside the compound:
And vice versa, if you update the value inside the compound, the provider will be automatically updated as well:
Once you've registered an entry provider for a key, the type under this key is constrained to the type of the entry provider.
val compound = Compound()
// no entry provider: type under key "a" can be changed
compound["a"] = 1
compound["a"] = "1"
// with entry provider: type is constrained to provider's type
var entry: String? by compound.entry<String>("a")
compound["a"] = 1 // IllegalArgumentException: kotlin.Int (value type) is not a subtype of kotlin.String? (entry type)
Defaulting
Defaulting entry providers cannot be null
. Instead, a default value is lazily generated using a predefined lambda
if there initially is no value under the given key.
val compound = Compound()
var entry: Int by compound.entry<Int>("a") { 1 }
println(entry) // 1
println(compound["a"]) // 1
Note that defaulting entry providers introduce an additional type constraint of non-nullability to the type under the
key, meaning entries cannot be removed (i.e. set to null
).
val compound = Compound()
// non-defaulting entry provider: value can be removed (set to null)
var entry: Int? by compound.entry<Int>("a")
compound["a"] = null
// default entry provider: value cannot be removed (set to null)
var entry1: Int by compound.entry<Int>("b") { 1 }
compound["b"] = null // IllegalArgumentException: kotlin.Nothing? (value type) is not a subtype of kotlin.Int (entry type)