diff --git a/README.md b/README.md index c31541f..e472435 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,6 @@ Monarch provides several feature flag types in the 'core' artifact. * `LongFeatureFlag` * `DoubleFeatureFlag` * `StringFeatureFlag` -* `ByteArrayFeatureFlag` ### Obtaining values diff --git a/core/src/commonMain/kotlin/io/github/kevincianfarini/monarch/FeatureFlag.kt b/core/src/commonMain/kotlin/io/github/kevincianfarini/monarch/FeatureFlag.kt index 5f0fc54..7b84491 100644 --- a/core/src/commonMain/kotlin/io/github/kevincianfarini/monarch/FeatureFlag.kt +++ b/core/src/commonMain/kotlin/io/github/kevincianfarini/monarch/FeatureFlag.kt @@ -49,11 +49,3 @@ public abstract class LongFeatureFlag( public override val key: String, public override val default: Long, ) : FeatureFlag - -/** - * A simple [Long] feature flag. - */ -public abstract class ByteArrayFeatureFlag( - public override val key: String, - public override val default: ByteArray, -) : FeatureFlag diff --git a/core/src/commonMain/kotlin/io/github/kevincianfarini/monarch/FeatureFlagDataStore.kt b/core/src/commonMain/kotlin/io/github/kevincianfarini/monarch/FeatureFlagDataStore.kt index 0d5a10c..9da4118 100644 --- a/core/src/commonMain/kotlin/io/github/kevincianfarini/monarch/FeatureFlagDataStore.kt +++ b/core/src/commonMain/kotlin/io/github/kevincianfarini/monarch/FeatureFlagDataStore.kt @@ -24,9 +24,4 @@ public interface FeatureFlagDataStore { * Get the [Long] value associated with [key] if present. Otherwise, return [default]. */ public fun getLong(key: String, default: Long): Long - - /** - * Get the [ByteArray] value associated with [key] if present. Otherwise, return [default]. - */ - public fun getByteArray(key: String, default: ByteArray): ByteArray } \ No newline at end of file diff --git a/core/src/commonMain/kotlin/io/github/kevincianfarini/monarch/InMemoryFeatureFlagDataStoreOverride.kt b/core/src/commonMain/kotlin/io/github/kevincianfarini/monarch/InMemoryFeatureFlagDataStoreOverride.kt index d840fe0..efd5e07 100644 --- a/core/src/commonMain/kotlin/io/github/kevincianfarini/monarch/InMemoryFeatureFlagDataStoreOverride.kt +++ b/core/src/commonMain/kotlin/io/github/kevincianfarini/monarch/InMemoryFeatureFlagDataStoreOverride.kt @@ -41,10 +41,6 @@ public class InMemoryFeatureFlagDataStoreOverride( return cache.getCachedValue(key) ?: delegate.getLong(key, default) } - public override fun getByteArray(key: String, default: ByteArray): ByteArray { - return cache.getCachedValue(key) ?: delegate.getByteArray(key, default) - } - public override fun observeBoolean(key: String, default: Boolean): Flow { return cache.observeCachedValue(key).flatMapLatest { cachedValue -> when (cachedValue) { @@ -81,15 +77,6 @@ public class InMemoryFeatureFlagDataStoreOverride( } } - public override fun observeByteArray(key: String, default: ByteArray): Flow { - return cache.observeCachedValue(key).flatMapLatest { cachedValue -> - when (cachedValue) { - null -> delegate.observeByteArray(key, default) - else -> flowOf(cachedValue) - } - } - } - public fun setBoolean(key: String, value: Boolean) { cache.update { map -> map + Pair(key, value) } } diff --git a/core/src/commonMain/kotlin/io/github/kevincianfarini/monarch/MixinFeatureFlagManager.kt b/core/src/commonMain/kotlin/io/github/kevincianfarini/monarch/MixinFeatureFlagManager.kt index e72784e..2b74655 100644 --- a/core/src/commonMain/kotlin/io/github/kevincianfarini/monarch/MixinFeatureFlagManager.kt +++ b/core/src/commonMain/kotlin/io/github/kevincianfarini/monarch/MixinFeatureFlagManager.kt @@ -21,7 +21,6 @@ public class MixinFeatureFlagManager( is StringFeatureFlag -> store.getString(flag.key, flag.default) as T is DoubleFeatureFlag -> store.getDouble(flag.key, flag.default) as T is LongFeatureFlag -> store.getLong(flag.key, flag.default) as T - is ByteArrayFeatureFlag -> store.getByteArray(flag.key, flag.default) as T else -> mixins.firstNotNullOfOrNull { delegate -> delegate.currentValueOfOrNull(flag, store) } ?: throw IllegalArgumentException("$flag is not a recognized feature flag.") diff --git a/core/src/commonMain/kotlin/io/github/kevincianfarini/monarch/ObservableFeatureFlagDataStore.kt b/core/src/commonMain/kotlin/io/github/kevincianfarini/monarch/ObservableFeatureFlagDataStore.kt index dcd0598..c332b2f 100644 --- a/core/src/commonMain/kotlin/io/github/kevincianfarini/monarch/ObservableFeatureFlagDataStore.kt +++ b/core/src/commonMain/kotlin/io/github/kevincianfarini/monarch/ObservableFeatureFlagDataStore.kt @@ -34,11 +34,4 @@ public interface ObservableFeatureFlagDataStore : FeatureFlagDataStore { * time of collection, and will emit again on each subsequent update for [key]. */ public fun observeLong(key: String, default: Long): Flow - - /** - * Return a [Flow] which emits updates to a [ByteArray] value associated with [key] if present. When no value is - * present for [key], the returned flow will emit [default]. The returned flow initially emits the value at the - * time of collection, and will emit again on each subsequent update for [key]. - */ - public fun observeByteArray(key: String, default: ByteArray): Flow } \ No newline at end of file diff --git a/core/src/commonMain/kotlin/io/github/kevincianfarini/monarch/ObservableMixinFeatureFlagManager.kt b/core/src/commonMain/kotlin/io/github/kevincianfarini/monarch/ObservableMixinFeatureFlagManager.kt index 6cafffa..42ce264 100644 --- a/core/src/commonMain/kotlin/io/github/kevincianfarini/monarch/ObservableMixinFeatureFlagManager.kt +++ b/core/src/commonMain/kotlin/io/github/kevincianfarini/monarch/ObservableMixinFeatureFlagManager.kt @@ -1,7 +1,6 @@ package io.github.kevincianfarini.monarch import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.map /** * A [ObservableFeatureFlagManager] implementation that allows extension via [mixins]. @@ -25,7 +24,6 @@ public class ObservableMixinFeatureFlagManager( is StringFeatureFlag -> store.observeString(flag.key, flag.default) as Flow is DoubleFeatureFlag -> store.observeDouble(flag.key, flag.default) as Flow is LongFeatureFlag -> store.observeLong(flag.key, flag.default) as Flow - is ByteArrayFeatureFlag -> store.observeByteArray(flag.key, flag.default) as Flow else -> mixins.firstNotNullOfOrNull { delegate -> delegate.valuesOfOrNull(flag, store) } ?: throw IllegalArgumentException("$flag is not a recognized feature flag.") diff --git a/core/src/commonTest/kotlin/io/github/kevincianfarini/monarch/InMemoryFeatureFlagDataStoreOverrideTest.kt b/core/src/commonTest/kotlin/io/github/kevincianfarini/monarch/InMemoryFeatureFlagDataStoreOverrideTest.kt index 420a110..44debf2 100644 --- a/core/src/commonTest/kotlin/io/github/kevincianfarini/monarch/InMemoryFeatureFlagDataStoreOverrideTest.kt +++ b/core/src/commonTest/kotlin/io/github/kevincianfarini/monarch/InMemoryFeatureFlagDataStoreOverrideTest.kt @@ -17,7 +17,6 @@ class InMemoryFeatureFlagDataStoreOverrideTest { Triple("correct", "incorrect") { getString(it, "incorrect") }, Triple(1.5, 3.0) { getDouble(it, 3.0) }, Triple(1L, 2L) { getLong(it, 2L) }, - Triple(byteArrayOf(0b1), byteArrayOf(0b0)) { getByteArray(it, byteArrayOf(0b0)) } ).forEach { (overrideValue, delegateValue, produceFn) -> testCacheOverridesDelegateSynchronousParameterized(overrideValue, delegateValue, produceFn) } @@ -47,7 +46,6 @@ class InMemoryFeatureFlagDataStoreOverrideTest { Pair("correct") { getString(it, "incorrect") }, Pair(3.0) { getDouble(it, 1.5) }, Pair(2L) { getLong(it, 1L) }, - Pair(byteArrayOf(0b0)) { getByteArray(it, byteArrayOf(0b1)) } ).forEach { (delegateValue, produceFn) -> testCacheFallsBackToDelegateSynchronousParameterized(delegateValue, produceFn) } @@ -73,7 +71,6 @@ class InMemoryFeatureFlagDataStoreOverrideTest { Triple("correct", "incorrect") { observeString(it, "incorrect") }, Triple(1.5, 3.0) { observeDouble(it, 3.0) }, Triple(1L, 2L) { observeLong(it, 2L) }, - Triple(byteArrayOf(0b1), byteArrayOf(0b0)) { observeByteArray(it, byteArrayOf(0b0)) } ).forEach { (overrideValue, delegateValue, produceFn) -> storeCacheOverridesDelegateFlowParameterized(overrideValue, delegateValue, produceFn) } @@ -105,7 +102,6 @@ class InMemoryFeatureFlagDataStoreOverrideTest { Pair("correct") { observeString(it, "incorrect") }, Pair(3.0) { observeDouble(it, 1.5) }, Pair(2L) { observeLong(it, 1L) }, - Pair(byteArrayOf(0b0)) { observeByteArray(it, byteArrayOf(0b1)) } ).forEach { (delegateValue, produceFn) -> storeCacheFallsBackToDelegateFlowParameterized(delegateValue, produceFn) } @@ -133,7 +129,6 @@ class InMemoryFeatureFlagDataStoreOverrideTest { Triple("correct", { setString(it, "also correct") }) { observeString(it, "incorrect") }, Triple(1.5, { setDouble(it, 3.0) }) { observeDouble(it, 4.5) }, Triple(1L, { setLong(it, 3L) }) { observeLong(it, 2L) }, - Triple(byteArrayOf(0b1), { setByteArray(it, byteArrayOf(0b0)) }) { observeByteArray(it, byteArrayOf(0b101)) } ).forEach { (initialValue, newValue, produceFn) -> writingToStoreCacheEmitsNewValueParameterized(initialValue, newValue, produceFn) } diff --git a/core/src/commonTest/kotlin/io/github/kevincianfarini/monarch/MixinFeatureFlagManagerTest.kt b/core/src/commonTest/kotlin/io/github/kevincianfarini/monarch/MixinFeatureFlagManagerTest.kt index f2d9e34..a77986b 100644 --- a/core/src/commonTest/kotlin/io/github/kevincianfarini/monarch/MixinFeatureFlagManagerTest.kt +++ b/core/src/commonTest/kotlin/io/github/kevincianfarini/monarch/MixinFeatureFlagManagerTest.kt @@ -52,19 +52,6 @@ class MixinFeatureFlagManagerTest { actual = manager().currentValueOf(LongFeature), ) - @Test fun `manager gets byte array value`() { - val store = InMemoryFeatureFlagDataStore().apply { setValue("byte", byteArrayOf(0b11)) } - assertContentEquals( - expected = byteArrayOf(0b11), - actual = manager(store).currentValueOf(ByteArrayFeature), - ) - } - - @Test fun `manager gets default byte array value`() = assertContentEquals( - expected = byteArrayOf(0b1), - actual = manager().currentValueOf(ByteArrayFeature), - ) - @Test fun `manager gets mixin value`() { val store = InMemoryFeatureFlagDataStore().apply { setValue("some_int", "1") } assertEquals( diff --git a/core/src/commonTest/kotlin/io/github/kevincianfarini/monarch/ObservableMixinFeatureFlagManagerTest.kt b/core/src/commonTest/kotlin/io/github/kevincianfarini/monarch/ObservableMixinFeatureFlagManagerTest.kt index 3dc5af2..9338f28 100644 --- a/core/src/commonTest/kotlin/io/github/kevincianfarini/monarch/ObservableMixinFeatureFlagManagerTest.kt +++ b/core/src/commonTest/kotlin/io/github/kevincianfarini/monarch/ObservableMixinFeatureFlagManagerTest.kt @@ -82,25 +82,6 @@ class ObservableMixinFeatureFlagManagerTest { } } - @Test fun `manager gets byte array value`() { - runBlocking { - val store = InMemoryFeatureFlagDataStore().apply { setValue("byte", byteArrayOf(0b11)) } - manager(store).valuesOf(ByteArrayFeature).test { - assertContentEquals(expected = byteArrayOf(0b11), actual = awaitItem()) - cancelAndIgnoreRemainingEvents() - } - } - } - - @Test fun `manager gets default byte array value`() { - runBlocking { - manager().valuesOf(ByteArrayFeature).test { - assertContentEquals(expected = byteArrayOf(0b1), actual = awaitItem()) - cancelAndIgnoreRemainingEvents() - } - } - } - @Test fun `manager gets mixin value`() { runBlocking { val store = InMemoryFeatureFlagDataStore().apply { setValue("some_int", "1") } diff --git a/core/src/commonTest/kotlin/io/github/kevincianfarini/monarch/flags.kt b/core/src/commonTest/kotlin/io/github/kevincianfarini/monarch/flags.kt index 9a0688e..73b8e33 100644 --- a/core/src/commonTest/kotlin/io/github/kevincianfarini/monarch/flags.kt +++ b/core/src/commonTest/kotlin/io/github/kevincianfarini/monarch/flags.kt @@ -9,7 +9,6 @@ object StringFeature : StringFeatureFlag(key = "foo", default = "blah") object BooleanFeature : BooleanFeatureFlag(key = "bool", default = false) object DoubleFeature : DoubleFeatureFlag(key = "double", default = 1.5) object LongFeature : LongFeatureFlag(key = "long", default = 1027L) -object ByteArrayFeature : ByteArrayFeatureFlag(key = "byte", default = byteArrayOf(0b1)) object IntFeatureFlag : FeatureFlag { override val key: String get() = "some_int" override val default = -1 diff --git a/integrations/environment-variable/src/commonMain/kotlin/io/github/kevincianfarini/monarch/environment/EnvironmentVariableFeatureFlagDataStore.kt b/integrations/environment-variable/src/commonMain/kotlin/io/github/kevincianfarini/monarch/environment/EnvironmentVariableFeatureFlagDataStore.kt index 225181b..e7bf000 100644 --- a/integrations/environment-variable/src/commonMain/kotlin/io/github/kevincianfarini/monarch/environment/EnvironmentVariableFeatureFlagDataStore.kt +++ b/integrations/environment-variable/src/commonMain/kotlin/io/github/kevincianfarini/monarch/environment/EnvironmentVariableFeatureFlagDataStore.kt @@ -39,25 +39,4 @@ public class EnvironmentVariableFeatureFlagDataStore internal constructor( val long = if (strictlyTyped) env?.toLong() else env?.toLongOrNull() return long ?: default } - - override fun getByteArray(key: String, default: ByteArray): ByteArray { - val env = getEnvironmentVariable(key) - val bytes = if (strictlyTyped) env?.decodeHexToByteArray() else env?.decodeHexToByteArrayOrNull() - return bytes ?: default - } -} - -private fun String.decodeHexToByteArrayOrNull(): ByteArray? = takeIf { it.length % 2 == 0 }?.let { string -> - ByteArray(string.length / 2) { index -> - val startIndex = index * 2 - val endIndex = startIndex + 1 - val byteString = string.substring(startIndex, endIndex + 1) - byteString.toByte(16) - } -} - -private fun String.decodeHexToByteArray(): ByteArray { - return requireNotNull(decodeHexToByteArrayOrNull()) { - "The input string $this is not a valid hex string." - } } \ No newline at end of file diff --git a/integrations/launch-darkly/src/androidMain/kotlin/io/github/kevincianfarini/monarch/launchdarkly/LaunchDarklyFeatureFlagDataStore.kt b/integrations/launch-darkly/src/androidMain/kotlin/io/github/kevincianfarini/monarch/launchdarkly/LaunchDarklyFeatureFlagDataStore.kt index dd1c22f..1ad35ed 100644 --- a/integrations/launch-darkly/src/androidMain/kotlin/io/github/kevincianfarini/monarch/launchdarkly/LaunchDarklyFeatureFlagDataStore.kt +++ b/integrations/launch-darkly/src/androidMain/kotlin/io/github/kevincianfarini/monarch/launchdarkly/LaunchDarklyFeatureFlagDataStore.kt @@ -35,10 +35,6 @@ private class LaunchDarklyFeatureFlagDataStore( return client.getValue(key, default) } - override fun getByteArray(key: String, default: ByteArray): ByteArray { - throw NotImplementedError("LaunchDarkly does not support ByteArray flags.") - } - override fun observeString(key: String, default: String): Flow = client.observeValue(key, default) override fun observeBoolean(key: String, default: Boolean): Flow = client.observeValue(key, default) @@ -46,10 +42,6 @@ private class LaunchDarklyFeatureFlagDataStore( override fun observeDouble(key: String, default: Double): Flow = client.observeValue(key, default) override fun observeLong(key: String, default: Long): Flow = client.observeValue(key, default) - - override fun observeByteArray(key: String, default: ByteArray): Flow { - throw NotImplementedError("LaunchDarkly does not support ByteArray flags.") - } } private inline fun LDClientInterface.observeValue(key: String, default: T): Flow { diff --git a/integrations/launch-darkly/src/commonTest/kotlin/io/github/kevincianfarini/monarch/launchdarkly/LaunchDarklyFeatureFlagDataStoreTest.kt b/integrations/launch-darkly/src/commonTest/kotlin/io/github/kevincianfarini/monarch/launchdarkly/LaunchDarklyFeatureFlagDataStoreTest.kt index 680b3a6..798acd1 100644 --- a/integrations/launch-darkly/src/commonTest/kotlin/io/github/kevincianfarini/monarch/launchdarkly/LaunchDarklyFeatureFlagDataStoreTest.kt +++ b/integrations/launch-darkly/src/commonTest/kotlin/io/github/kevincianfarini/monarch/launchdarkly/LaunchDarklyFeatureFlagDataStoreTest.kt @@ -53,13 +53,6 @@ class LaunchDarklyFeatureFlagDataStoreTest { assertEquals("non_default", dataStore.getString("key", "default")) } - @Test fun getting_byte_array_errors() = runTest { - val (dataStore, _) = sut() - assertFailsWith { - dataStore.getByteArray("key", byteArrayOf()) - } - } - @Test fun getting_string_from_json_flag_returns_value() { val (dataStore, mutate) = sut() val expected = Thing(1, 2) @@ -164,13 +157,6 @@ class LaunchDarklyFeatureFlagDataStoreTest { } } - @Test fun observing_byte_array_errors() = runTest { - val (dataStore, _) = sut() - assertFailsWith { - dataStore.observeByteArray("key", byteArrayOf()) - } - } - @Test fun observing_json_string_emits_value_updates() = runTest { val (dataStore, mutate) = sut() val first = Thing(1, 2) diff --git a/integrations/launch-darkly/src/iosMain/kotlin/io/github/kevincianfarini/monarch/launchdarkly/LaunchDarklyFeatureFlagDataStore.kt b/integrations/launch-darkly/src/iosMain/kotlin/io/github/kevincianfarini/monarch/launchdarkly/LaunchDarklyFeatureFlagDataStore.kt index 0096556..1d9f694 100644 --- a/integrations/launch-darkly/src/iosMain/kotlin/io/github/kevincianfarini/monarch/launchdarkly/LaunchDarklyFeatureFlagDataStore.kt +++ b/integrations/launch-darkly/src/iosMain/kotlin/io/github/kevincianfarini/monarch/launchdarkly/LaunchDarklyFeatureFlagDataStore.kt @@ -35,10 +35,6 @@ private class LaunchDarklyFeatureFlagDataStore( return shim.getValue(key, default) } - override fun getByteArray(key: String, default: ByteArray): ByteArray { - throw NotImplementedError("LaunchDarkly does not support ByteArray flags.") - } - override fun observeString(key: String, default: String): Flow { return shim.observeValue(key, default) } @@ -54,10 +50,6 @@ private class LaunchDarklyFeatureFlagDataStore( override fun observeLong(key: String, default: Long): Flow { return shim.observeValue(key, default) } - - override fun observeByteArray(key: String, default: ByteArray): Flow { - throw NotImplementedError("LaunchDarkly does not support ByteArray flags.") - } } @OptIn(ExperimentalForeignApi::class) diff --git a/test/src/commonMain/kotlin/io/github/kevincianfarini/monarch/InMemoryFeatureFlagDataStore.kt b/test/src/commonMain/kotlin/io/github/kevincianfarini/monarch/InMemoryFeatureFlagDataStore.kt index 24a9ded..ac916ae 100644 --- a/test/src/commonMain/kotlin/io/github/kevincianfarini/monarch/InMemoryFeatureFlagDataStore.kt +++ b/test/src/commonMain/kotlin/io/github/kevincianfarini/monarch/InMemoryFeatureFlagDataStore.kt @@ -22,10 +22,6 @@ public class InMemoryFeatureFlagDataStore : ObservableFeatureFlagDataStore { return store.observeValue(key, default) } - public override fun observeByteArray(key: String, default: ByteArray): Flow { - return store.observeValue(key, default) - } - public override fun getBoolean(key: String, default: Boolean): Boolean { return store.getValue(key, default) } @@ -42,10 +38,6 @@ public class InMemoryFeatureFlagDataStore : ObservableFeatureFlagDataStore { return store.getValue(key, default) } - public override fun getByteArray(key: String, default: ByteArray): ByteArray { - return store.getValue(key, default) - } - public fun setValue(key: String, value: Any?) { store.update { map -> map.plus(key to value)