Skip to content

Commit 913c08c

Browse files
committed
Make the api explicit and efficient
1 parent df3134c commit 913c08c

File tree

5 files changed

+56
-33
lines changed

5 files changed

+56
-33
lines changed

feature-flags/public/src/main/java/com/hadilq/guidomia/featureflags/api/CommandExecutor.kt

+16-4
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,23 @@ fun <reified IN : Command, reified OUT : Command> CommandExecutor.exe(
3333
execute(input, IN::class, OUT::class)
3434

3535
suspend inline
36-
fun <reified IN : Command, reified OUT : Command> CommandExecutor.available(
36+
fun <reified IN : Command, reified OUT : Command> CommandExecutor.featureFlag(
3737
input: IN,
3838
@Suppress("UNUSED_PARAMETER") output: KClass<OUT>,
39-
): OUT? =
39+
): FeatureFlag<OUT> =
4040
when (val commandResult: CommandResult<OUT> = exe(input)) {
41-
is Available<*> -> commandResult.command as OUT
42-
else -> null
41+
is Available<*> -> FeatureFlag.On(commandResult.command as OUT)
42+
else -> FeatureFlag.Off()
4343
}
44+
45+
sealed class FeatureFlag<T> {
46+
abstract fun <O> to(map: T.() -> O): FeatureFlag<O>
47+
48+
class On<T>(val value: T) : FeatureFlag<T>() {
49+
override fun <O> to(map: T.() -> O): FeatureFlag<O> = On(value.map())
50+
}
51+
52+
class Off<T> : FeatureFlag<T>() {
53+
override fun <O> to(map: T.() -> O): FeatureFlag<O> = Off()
54+
}
55+
}

guidomia/impl/src/main/java/com/hadilq/guidomia/guidomia/impl/data/datasource/CarDatabaseDataSource.kt

+24-13
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ import com.hadilq.guidomia.database.api.CarDataEntityCommand
1919
import com.hadilq.guidomia.database.api.GetCarEntityCommand
2020
import com.hadilq.guidomia.database.api.GetCarEntityCommandResult
2121
import com.hadilq.guidomia.featureflags.api.CommandExecutor
22-
import com.hadilq.guidomia.featureflags.api.available
22+
import com.hadilq.guidomia.featureflags.api.FeatureFlag
23+
import com.hadilq.guidomia.featureflags.api.featureFlag
2324
import com.hadilq.guidomia.guidomia.impl.data.mapper.CarDatabaseMapper
2425
import com.hadilq.guidomia.guidomia.impl.domain.entity.CarEntity
2526
import javax.inject.Inject
@@ -29,22 +30,32 @@ class CarDatabaseDataSource @Inject constructor(
2930
private val mapper: CarDatabaseMapper,
3031
) {
3132

32-
private var command: CarDataEntityCommand? = null
33+
private var command: FeatureFlag<CarDataEntityCommand>? = null
3334

34-
suspend fun availableCommand(): Boolean =
35-
if (command != null) {
36-
true
37-
} else {
38-
command = executor.available(GetCarEntityCommand(), GetCarEntityCommandResult::class)?.result
39-
command != null
40-
}
35+
suspend fun featureFlag(): Boolean = when (fetchFlag()) {
36+
is FeatureFlag.On -> true
37+
is FeatureFlag.Off -> false
38+
}
4139

42-
suspend fun isEmpty(): Boolean = command?.isEmpty() ?: true
40+
suspend fun isEmpty(): Boolean = when (val flag = fetchFlag()) {
41+
is FeatureFlag.On -> flag.value.isEmpty()
42+
is FeatureFlag.Off -> true
43+
}
4344

44-
suspend fun fetchCars(): List<CarEntity> =
45-
command?.getAll()?.map { mapper.map(it) } ?: emptyList()
45+
suspend fun fetchCars(): List<CarEntity> = when (val flag = fetchFlag()) {
46+
is FeatureFlag.On -> flag.value.getAll().map { mapper.map(it) }
47+
is FeatureFlag.Off -> emptyList()
48+
}
4649

4750
suspend fun save(cars: List<CarEntity>) {
48-
command?.insertAll(cars.map { mapper.map(it) })
51+
when (val flag = fetchFlag()) {
52+
is FeatureFlag.On -> flag.value.insertAll(cars.map { mapper.map(it) })
53+
}
54+
}
55+
56+
private suspend fun fetchFlag(): FeatureFlag<CarDataEntityCommand> = command ?: run {
57+
executor.featureFlag(GetCarEntityCommand(), GetCarEntityCommandResult::class)
58+
.to { result }
59+
.also { command = it }
4960
}
5061
}

guidomia/impl/src/main/java/com/hadilq/guidomia/guidomia/impl/data/repository/CarsRepository.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class CarsRepository @Inject constructor(
3131
fun getCars(): Flow<List<CarEntity>> =
3232
if (cacheDataSource.caching.isEmpty()) {
3333
flow {
34-
if (!carDatabaseDataSource.availableCommand() || carDatabaseDataSource.isEmpty()) {
34+
if (!carDatabaseDataSource.featureFlag() || carDatabaseDataSource.isEmpty()) {
3535
emitAll(carsDataSource.fetchCars()
3636
.onEach { carDatabaseDataSource.save(it) }
3737
.onEach { cacheDataSource.caching = it }

guidomia/impl/src/test/java/com/hadilq/guidomia/guidomia/impl/data/repository/CarRepositoryTest.kt

+3-3
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ internal class CarRepositoryTest {
4848
val repository = CarsRepository(carsDataSource, cacheDataSource, carDatabaseDataSource)
4949
every { cacheDataSource.caching } returns listOf()
5050
coEvery { carDatabaseDataSource.isEmpty() } returns true
51-
coEvery { carDatabaseDataSource.availableCommand() } returns true
51+
coEvery { carDatabaseDataSource.featureFlag() } returns true
5252
every { carsDataSource.fetchCars() } returns flowOf()
5353

5454
repository.getCars().collect()
@@ -63,7 +63,7 @@ internal class CarRepositoryTest {
6363
val repository = CarsRepository(carsDataSource, cacheDataSource, carDatabaseDataSource)
6464
every { cacheDataSource.caching } returns listOf()
6565
coEvery { carDatabaseDataSource.isEmpty() } returns true
66-
coEvery { carDatabaseDataSource.availableCommand() } returns false
66+
coEvery { carDatabaseDataSource.featureFlag() } returns false
6767
every { carsDataSource.fetchCars() } returns flowOf()
6868

6969
repository.getCars().collect()
@@ -78,7 +78,7 @@ internal class CarRepositoryTest {
7878
val repository = CarsRepository(carsDataSource, cacheDataSource, carDatabaseDataSource)
7979
every { cacheDataSource.caching } returns listOf()
8080
coEvery { carDatabaseDataSource.isEmpty() } returns false
81-
coEvery { carDatabaseDataSource.availableCommand() } returns true
81+
coEvery { carDatabaseDataSource.featureFlag() } returns true
8282
coEvery { carDatabaseDataSource.fetchCars() } returns listOf()
8383

8484
repository.getCars().collect()

single-activity/impl/src/main/java/com/hadilq/guidomia/singleactivity/impl/SingleActivity.kt

+12-12
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ import com.hadilq.guidomia.core.api.viewBinding
2323
import com.hadilq.guidomia.di.api.SingleActivityScope
2424
import com.hadilq.guidomia.di.api.SingleIn
2525
import com.hadilq.guidomia.featureflags.api.CommandExecutor
26-
import com.hadilq.guidomia.featureflags.api.available
26+
import com.hadilq.guidomia.featureflags.api.FeatureFlag
27+
import com.hadilq.guidomia.featureflags.api.featureFlag
2728
import com.hadilq.guidomia.guidomia.api.GetGuidomiaNavigatorFactoryCommand
2829
import com.hadilq.guidomia.guidomia.api.GetGuidomiaNavigatorFactoryCommandResult
2930
import com.hadilq.guidomia.guidomia.api.GuidomiaNavigatorFactory
@@ -44,7 +45,7 @@ class SingleActivity : AppCompatActivity() {
4445
@Inject
4546
internal lateinit var executor: CommandExecutor
4647

47-
private var guidomiaNavigatorFactory: GuidomiaNavigatorFactory? = null
48+
private var guidomiaNavigatorFactory: FeatureFlag<GuidomiaNavigatorFactory>? = null
4849

4950
private val binding by viewBinding { ActivityMainBinding.inflate(layoutInflater) }
5051

@@ -66,19 +67,18 @@ class SingleActivity : AppCompatActivity() {
6667
}
6768

6869
private fun openFirstPossiblePage() = lifecycleScope.launchWhenCreated {
69-
if (guidomiaNavigatorFactoryAvailable()) {
70-
guidomiaNavigatorFactory?.create(this@SingleActivity)?.commit()
70+
when (val flag = fetchFlag()) {
71+
is FeatureFlag.On -> flag.value.create(this@SingleActivity).commit()
7172
}
7273
}
7374

74-
private suspend fun guidomiaNavigatorFactoryAvailable(): Boolean =
75-
if (guidomiaNavigatorFactory != null) {
76-
true
77-
} else {
78-
guidomiaNavigatorFactory = executor.available(
75+
private suspend fun fetchFlag(): FeatureFlag<GuidomiaNavigatorFactory> =
76+
guidomiaNavigatorFactory ?: run {
77+
executor.featureFlag(
7978
GetGuidomiaNavigatorFactoryCommand(),
80-
GetGuidomiaNavigatorFactoryCommandResult::class
81-
)?.result
82-
guidomiaNavigatorFactory != null
79+
GetGuidomiaNavigatorFactoryCommandResult::class,
80+
).to { result }
81+
.also { guidomiaNavigatorFactory = it }
8382
}
83+
8484
}

0 commit comments

Comments
 (0)