• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2024 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 platform.test.motion.golden
18 
19 import org.json.JSONArray
20 
21 fun Float.asDataPoint() = DataPointTypes.float.makeDataPoint(this)
22 
23 fun Boolean.asDataPoint() = DataPointTypes.boolean.makeDataPoint(this)
24 
25 fun Int.asDataPoint() = DataPointTypes.int.makeDataPoint(this)
26 
27 fun String.asDataPoint() = DataPointTypes.string.makeDataPoint(this)
28 
29 /** [DataPointType] implementations for core Kotlin types. */
30 object DataPointTypes {
31 
32     val boolean: DataPointType<Boolean> =
33         DataPointType(
34             "boolean",
35             jsonToValue = {
36                 when {
37                     it is Boolean -> it
38                     it is String && "true".equals(it, ignoreCase = true) -> true
39                     it is String && "false".equals(it, ignoreCase = true) -> false
40                     else -> throw UnknownTypeException()
41                 }
42             },
43             valueToJson = { it },
44         )
45 
46     private const val NAN_STRING = "NaN"
47     private const val POSITIVE_INFINITY_STRING = "+∞"
48     private const val NEGATIVE_INFINITY_STRING = "-∞"
49 
50     val float: DataPointType<Float> =
51         DataPointType(
52             "float",
53             jsonToValue = {
54                 when (it) {
55                     is Float -> it
56                     is Number -> it.toFloat()
57                     NAN_STRING -> Float.NaN
58                     POSITIVE_INFINITY_STRING -> Float.POSITIVE_INFINITY
59                     NEGATIVE_INFINITY_STRING -> Float.NEGATIVE_INFINITY
60                     is String -> it.toFloatOrNull() ?: throw UnknownTypeException()
61                     else -> throw UnknownTypeException()
62                 }
63             },
64             valueToJson = {
65                 when {
66                     it.isFinite() -> it
67                     it.isNaN() -> NAN_STRING
68                     it == Float.NEGATIVE_INFINITY -> NEGATIVE_INFINITY_STRING
69                     it == Float.POSITIVE_INFINITY -> POSITIVE_INFINITY_STRING
70                     else -> it
71                 }
72             },
73         )
74 
75     val int: DataPointType<Int> =
76         DataPointType(
77             "int",
78             jsonToValue = {
79                 when (it) {
80                     is Int -> it
81                     is Number -> it.toInt()
82                     is String -> it.toIntOrNull() ?: throw UnknownTypeException()
83                     else -> throw UnknownTypeException()
84                 }
85             },
86             valueToJson = { it },
87         )
88 
89     val string: DataPointType<String> =
90         DataPointType("string", jsonToValue = { it.toString() }, valueToJson = { it })
91 
92     /**
93      * Creates a [DataPointType] to serialize a list of values in an array, using [dataPointType].
94      */
95     fun <T : Any> listOf(dataPointType: DataPointType<T>): DataPointType<List<T>> {
96         return DataPointType(
97             "${dataPointType.typeName}[]",
98             jsonToValue = {
99                 when (it) {
100                     is JSONArray ->
101                         List(it.length()) { index ->
102                             val dataPoint = dataPointType.fromJson(it.get(index))
103                             if (dataPoint !is ValueDataPoint<T>) {
104                                 throw UnknownTypeException()
105                             }
106                             dataPoint.value
107                         }
108                     else -> throw UnknownTypeException()
109                 }
110             },
111             valueToJson = {
112                 JSONArray().apply { it.forEach { value -> put(dataPointType.toJson(value)) } }
113             },
114         )
115     }
116 }
117