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