perf: mark Compose state types as @Immutable

Compose compiler reports showed DownloadState's sealed root as Uncertain
and DownloadProgressState/SettingsUiState as runtime stability, so
skippability checks were deferred to runtime. The annotations make them
compile-time stable and turn any future mutable field into an explicit
contract break.
This commit is contained in:
2026-09-01 17:28:17 +08:00
parent 70faf71f99
commit 5126c19f3c
5 changed files with 15 additions and 0 deletions
@@ -1,5 +1,8 @@
package com.example.research package com.example.research
import androidx.compose.runtime.Immutable
@Immutable
sealed interface DictionaryStatus { sealed interface DictionaryStatus {
data object Unknown : DictionaryStatus data object Unknown : DictionaryStatus
data object Checking : DictionaryStatus data object Checking : DictionaryStatus
@@ -1,5 +1,7 @@
package com.example.research.core.domain.model package com.example.research.core.domain.model
import androidx.compose.runtime.Immutable
/** /**
* Snapshot of an ongoing indexing operation. * Snapshot of an ongoing indexing operation.
* *
@@ -7,6 +9,7 @@ package com.example.research.core.domain.model
* aggregates a file-size-weighted sum across files incrementally while * aggregates a file-size-weighted sum across files incrementally while
* indexing, so reading it is O(1). * indexing, so reading it is O(1).
*/ */
@Immutable
data class IndexingProgress( data class IndexingProgress(
val isIndexing: Boolean = false, val isIndexing: Boolean = false,
val progress: Float = 0f, val progress: Float = 0f,
@@ -1,4 +1,8 @@
package com.example.research.feature.download.model package com.example.research.feature.download.model
import androidx.compose.runtime.Immutable
@Immutable
sealed class DownloadState { sealed class DownloadState {
data object Idle : DownloadState() data object Idle : DownloadState()
data object Loading : DownloadState() data object Loading : DownloadState()
@@ -1,5 +1,8 @@
package com.example.research.ui.settings package com.example.research.ui.settings
import androidx.compose.runtime.Immutable
@Immutable
sealed interface ImportState { sealed interface ImportState {
data object Idle : ImportState data object Idle : ImportState
data class Importing(val progress: Float) : ImportState data class Importing(val progress: Float) : ImportState
@@ -1,6 +1,7 @@
package com.example.research.ui.settings package com.example.research.ui.settings
import android.net.Uri import android.net.Uri
import androidx.compose.runtime.Immutable
import com.example.research.core.domain.model.AppTheme import com.example.research.core.domain.model.AppTheme
import com.example.research.core.domain.model.Dictionary import com.example.research.core.domain.model.Dictionary
import com.example.research.core.domain.model.DictionarySource import com.example.research.core.domain.model.DictionarySource
@@ -8,6 +9,7 @@ import com.example.research.core.domain.model.IndexingProgress
import com.example.research.DictionaryStatus import com.example.research.DictionaryStatus
import com.example.research.feature.download.model.DownloadState import com.example.research.feature.download.model.DownloadState
@Immutable
data class SettingsUiState( data class SettingsUiState(
val theme: AppTheme = AppTheme.SYSTEM, val theme: AppTheme = AppTheme.SYSTEM,
val language: String = "system", val language: String = "system",