From a1736892495c348cef7cceea5fc468a98b160e88 Mon Sep 17 00:00:00 2001 From: green-nick Date: Wed, 23 Oct 2019 11:08:21 +0300 Subject: [PATCH] - create mapNotNull mapper; - update README; --- README.md | 12 +++++ .../properties/generic/PropertiesExt.kt | 13 +++++ .../generic/PropertiesMappingTest.kt | 48 +++++++++++++++++++ 3 files changed, 73 insertions(+) diff --git a/README.md b/README.md index b12e946..5e41e32 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,18 @@ val property = propertyOf("Hello") val length: MutableProperty = property.map { it.length } // will contain 5 ``` Also notice that mapped value will be triggered on all updates of origin one. + +Besides that, there is mapper for nullable properties: +``` +val origin = propertyOf(null) + +val length: MutableProperty = property.mapNotNull(0) { it.length } // will contain 0 + +origin.value = "hello" +length.value == 5 +``` +If init value of origin property is `null`, default value will be used for initialization. +All non-null set values will be mapped. #### Addition: You can add two different properties and get new one and receive all updates pushed to origins as Pair of their values: ``` diff --git a/src/main/java/com/github/greennick/properties/generic/PropertiesExt.kt b/src/main/java/com/github/greennick/properties/generic/PropertiesExt.kt index 5003093..3fc0df0 100644 --- a/src/main/java/com/github/greennick/properties/generic/PropertiesExt.kt +++ b/src/main/java/com/github/greennick/properties/generic/PropertiesExt.kt @@ -54,6 +54,19 @@ fun Property.map(mapper: (T) -> R): MutableProperty { return new } +fun Property.mapNotNull(default: R, mapper: (T) -> R): MutableProperty { + val init = this.value + val new = if (init == null) { + propertyOf(default) + } else { + propertyOf(mapper(init)) + } + + this.subscribe { new.value = mapper(it ?: return@subscribe) } + + return new +} + fun Property.zipWith(another: Property, zipper: (T1, T2) -> E): MutableProperty { val new = propertyOf(zipper(this.value, another.value)) diff --git a/src/test/java/com/github/greennick/properties/generic/PropertiesMappingTest.kt b/src/test/java/com/github/greennick/properties/generic/PropertiesMappingTest.kt index 26f1e00..bdbd681 100644 --- a/src/test/java/com/github/greennick/properties/generic/PropertiesMappingTest.kt +++ b/src/test/java/com/github/greennick/properties/generic/PropertiesMappingTest.kt @@ -26,4 +26,52 @@ class PropertiesMappingTest { assert(mapped.value == newValue.length) } + + @Test + fun `property got default instead of mapped null value`() { + val default = 2 + + val origin = propertyOf(null) + val mapped = origin.mapNotNull(default) { it.length } + + assert(mapped.value == default) + } + + @Test + fun `property got nonnull mapped value`() { + val default = 0 + val initValue = "hello" + + val origin = propertyOf(initValue) + val mapped = origin.mapNotNull(default) { it.length } + + assert(mapped.value == initValue.length) + assert(mapped.value != default) + } + + @Test + fun `mapped property receive updated nonnull value`() { + val default = 0 + val origin = propertyOf("hello") + + val mapped = origin.mapNotNull(default) { it.length } + + val newValue = "worlds!!!" + origin.value = newValue + + assert(mapped.value == newValue.length) + } + + @Test + fun `mapped property doesn't receive updated nullable value`() { + val default = 0 + val init = "hello" + val origin = propertyOf(init) + + val mapped = origin.mapNotNull(default) { it.length } + + origin.value = null + + assert(mapped.value == init.length) + } } \ No newline at end of file