Skip to content

Generated Code with Mutekt

Shreyas Patil edited this page Mar 22, 2023 · 2 revisions

Assuming the following definition of a state model:

@GenerateMutableModel
interface NotesState {
    val isLoading: Boolean
    val notes: List<String>
    val error: String?
}

Under the hood, Mutekt generates the following code for the above example model.

/**
 * Mutable state model for [NotesState]
 */
public interface MutableNotesState : NotesState, MutektMutableState<NotesState, MutableNotesState> {
    public override var isLoading: Boolean

    public override var notes: List<String>

    public override var error: String?
}

private data class ImmutableNotesState(
    public override val isLoading: Boolean,
    public override val notes: List<String>,
    public override val error: String?,
) : NotesState

private class MutableNotesStateImpl(
    isLoading: Boolean,
    notes: List<String>,
    error: String?,
) : MutableNotesState {
    private val _atomicExecutor: AtomicExecutor = AtomicExecutor()

    private val _isLoading: MutableStateFlow<Boolean> = MutableStateFlow(isLoading)

    public override var isLoading: Boolean
        get() = _isLoading.value
        set(`value`) {
            _isLoading.value = value
        }

    private val _notes: MutableStateFlow<List<String>> = MutableStateFlow(notes)

    public override var notes: List<String>
        get() = _notes.value
        set(`value`) {
            _notes.value = value
        }

    private val _error: MutableStateFlow<String?> = MutableStateFlow(error)

    public override var error: String?
        get() = _error.value
        set(`value`) {
            _error.value = value
        }

    private val _immutableStateFlowImpl: StateFlow<NotesState> = object : StateFlow<NotesState> {
        public override val replayCache: List<NotesState>
            get() = listOf(value)

        public override val `value`: NotesState
            get() = ImmutableNotesState(
                isLoading = _isLoading.value,
                notes = _notes.value,
                error = _error.value,
            )

        public override suspend fun collect(collector: FlowCollector<NotesState>): Nothing =
            coroutineScope {
                combine(_atomicExecutor.executing, _isLoading, _notes, _error) { params ->
                    val isUpdating = params[0] as Boolean
                    if (!isUpdating) {
                        value
                    } else {
                        null
                    }
                }
                    .filterNotNull()
                    .stateIn(this)
                    .collect(collector)
            }

    }


    public override fun asStateFlow(): StateFlow<NotesState> = _immutableStateFlowImpl

    public override fun update(mutate: MutableNotesState.() -> Unit): Unit {
        _atomicExecutor.execute { mutate() }
    }
}

/**
 * Creates an instance of state model [MutableNotesState]
 */
public fun MutableNotesState(
    isLoading: Boolean,
    notes: List<String>,
    error: String?,
): MutableNotesState = MutableNotesStateImpl(isLoading, notes, error)

/**
 * Creates an instance of state model [NotesState]
 */
public fun NotesState(
    isLoading: Boolean,
    notes: List<String>,
    error: String?,
): NotesState = ImmutableNotesState(isLoading, notes, error)

/**
 * Creates a mutable [NotesState] instance from this state model
 */
public fun NotesState.mutable(): MutableNotesState = MutableNotesState(isLoading, notes, error)
Clone this wiki locally