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