blob: 97066397fb44653177fc5eafb022de0679ab5704 [file] [log] [blame]
package com.android.onboarding.contracts
import android.content.Intent
/** Marks functions that read or write intent data */
@DslMarker internal annotation class IntentManipulationDsl
/** Interface for writing an object to an [Intent] and reading the same object from an [Intent]. */
interface IntentSerializer<V> {
/**
* Utility intent builder that allows writing the [arg] and customising the intent settings
*
* @param arg to serialize into intent extras
* @param builder to configure the intent
*/
@IntentManipulationDsl
fun Intent(arg: V, builder: Intent.() -> Unit = {}): Intent =
Intent().also {
write(it, arg)
it.builder()
}
/**
* Utility intent builder that allows writing the [arg] and customising the intent settings
*
* @param action the intent should send
* @param arg to serialize into intent extras
* @param builder to configure the intent
*/
@IntentManipulationDsl
fun Intent(action: String, arg: V, builder: Intent.() -> Unit = {}): Intent =
Intent(arg) {
this.action = action
builder()
}
fun write(intent: Intent, value: V)
fun read(intent: Intent): V
/**
* Calls [read] to get the value, but instead of throwing an error during read failures it instead
* catches it, prints stack trace and returns null
*/
fun readOrNull(intent: Intent): V? =
runCatching { read(intent) }.onFailure(Throwable::printStackTrace).getOrNull()
}
/**
* A serializer that does not expose [Intent] directly and instead works via [NodeAwareIntentScope]
* abstraction that can be observed
*
* TODO This is living as a separate opt-in interface for now, but we should look into incorporating
* it inside the contract class to make methods enforceable and protected
*/
interface NodeAwareIntentSerializer<V> : IntentSerializer<V>, NodeAware {
fun NodeAwareIntentScope.write(value: V)
fun NodeAwareIntentScope.read(): V
override fun write(intent: Intent, value: V): Unit =
NodeAwareIntentScope(nodeId, intent).use { it.write(value) }
override fun read(intent: Intent): V = NodeAwareIntentScope(nodeId, intent).use { it.read() }
}