1 /*
2 * Copyright 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package androidx.compose.runtime.saveable
18
19 /**
20 * The [Saver] describes how the object of [Original] class can be simplified and converted into
21 * something which is [Saveable].
22 *
23 * What types can be saved is defined by [SaveableStateRegistry], by default everything which can be
24 * stored in the Bundle class can be saved. The implementations can check that the provided value
25 * can be saved via [SaverScope.canBeSaved]
26 *
27 * You can pass the implementations of this class as a parameter for [rememberSaveable].
28 *
29 * @sample androidx.compose.runtime.saveable.samples.CustomSaverSample
30 */
31 interface Saver<Original, Saveable : Any> {
32 /** Convert the value into a saveable one. If null is returned the value will not be saved. */
savenull33 fun SaverScope.save(value: Original): Saveable?
34
35 /**
36 * Convert the restored value back to the original Class. If null is returned the value will not
37 * be restored and would be initialized again instead.
38 */
39 fun restore(value: Saveable): Original?
40 }
41
42 /**
43 * The [Saver] describes how the object of [Original] class can be simplified and converted into
44 * something which is [Saveable].
45 *
46 * What types can be saved is defined by [SaveableStateRegistry], by default everything which can be
47 * stored in the Bundle class can be saved. The implementations can check that the provided value
48 * can be saved via [SaverScope.canBeSaved]
49 *
50 * You can pass the implementations of this class as a parameter for [rememberSaveable].
51 *
52 * @sample androidx.compose.runtime.saveable.samples.CustomSaverSample
53 * @param save Defines how to convert the value into a saveable one. If null is returned the value
54 * will not be saved.
55 * @param restore Defines how to convert the restored value back to the original Class. If null is
56 * returned the value will not be restored and would be initialized again instead.
57 */
58 fun <Original, Saveable : Any> Saver(
59 save: SaverScope.(value: Original) -> Saveable?,
60 restore: (value: Saveable) -> Original?
61 ): Saver<Original, Saveable> {
62 return object : Saver<Original, Saveable> {
63 override fun SaverScope.save(value: Original) = save.invoke(this, value)
64
65 override fun restore(value: Saveable) = restore.invoke(value)
66 }
67 }
68
69 /**
70 * Scope used in [Saver.save].
71 *
72 * @see Saver
73 */
interfacenull74 fun interface SaverScope {
75 /**
76 * What types can be saved is defined by [SaveableStateRegistry], by default everything which
77 * can be stored in the Bundle class can be saved.
78 */
79 fun canBeSaved(value: Any): Boolean
80 }
81
82 /**
83 * The default implementation of [Saver] which does not perform any conversion.
84 *
85 * It is used by [rememberSaveable] by default.
86 *
87 * @see Saver
88 */
autoSavernull89 fun <T> autoSaver(): Saver<T, Any> = @Suppress("UNCHECKED_CAST") (AutoSaver as Saver<T, Any>)
90
91 private val AutoSaver = Saver<Any?, Any>(save = { it }, restore = { it })
92