SavedStateHandleFactory.kt
/*
* Copyright 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.navigation.testing
import androidx.lifecycle.SavedStateHandle
import androidx.navigation.NavDestination
import androidx.navigation.NavDestinationBuilder
import androidx.navigation.NavType
import androidx.navigation.Navigator
import androidx.navigation.get
import androidx.navigation.serialization.generateRouteWithArgs
import kotlin.reflect.KType
/**
* SavedStateHandle constructor to create a SavedStateHandle with a serializable object.
*
* Returns a [SavedStateHandle] populated with arguments from [route].
*
* @param route The route to extract argument values from
* @param typeMap A mapping of KType to custom NavType<*> in the [route]. May be empty if
* [route] does not use custom NavTypes.
*/
@Suppress("DEPRECATION")
public operator fun SavedStateHandle.Companion.invoke(
route: Any,
typeMap: Map<KType, @JvmSuppressWildcards NavType<*>> = emptyMap()
): SavedStateHandle {
val dest = NavDestinationBuilder(
TestNavigatorProvider().get<Navigator<NavDestination>>("test"),
route::class,
typeMap
).build()
val map = dest.arguments.mapValues { it.value.type }
val deeplink = route.generateRouteWithArgs(map)
val matching = dest.matchDeepLink(deeplink)
checkNotNull(matching) {
"Cannot match route [$deeplink] to [${route::class.simpleName}]"
}
if (dest.arguments.isNotEmpty()) {
checkNotNull(matching.matchingArgs) {
"Missing arguments from route [$deeplink]"
}
}
val finalMap: MutableMap<String, Any?> = mutableMapOf()
matching.matchingArgs?.keySet()?.forEach { key ->
finalMap[key] = matching.matchingArgs!![key]
}
return SavedStateHandle(finalMap)
}