1 /* 2 * Copyright (C) 2022 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 com.android.libraries.pcc.chronicle.util 18 19 /** 20 * A [MutableTypedMap] is a mutable, type-safe map that allows for heterogeneously typed values. 21 * 22 * This map is keyed using implementations of the [Key] interface. A [Key] implementation will 23 * specify the class type of a corresponding value to be stored in the map. 24 * 25 * Example: 26 * 27 * ```kotlin 28 * object NameKey : Key<String> 29 * object IdKey : Key<Int> 30 * 31 * map[NameKey] = "First Last" 32 * map[IdKey] = 123 33 * ``` 34 */ 35 class MutableTypedMap(val map: MutableMap<Key<Any>, Any> = mutableMapOf()) { 36 37 /** Set a value of type T for the given key */ setnull38 operator fun <T : Any> set(key: Key<T>, value: T) { 39 @Suppress("UNCHECKED_CAST") 40 map[key as Key<Any>] = value 41 } 42 43 /** Get object of type T or null if not present */ getnull44 operator fun <T> get(key: Key<T>): T? { 45 @Suppress("UNCHECKED_CAST") return map[key as Key<Any>] as T 46 } 47 48 /** Get immutable version of this [MutableTypedMap] */ toTypedMapnull49 fun toTypedMap() = TypedMap(this) 50 51 override fun equals(other: Any?): Boolean { 52 if (this === other) return true 53 if (other !is MutableTypedMap) return false 54 if (map != other.map) return false 55 return true 56 } 57 hashCodenull58 override fun hashCode(): Int { 59 return map.hashCode() 60 } 61 } 62 63 /** 64 * Keying structure for the [TypedMap] that can be associated with a value of type T, where T is a 65 * basic type (https://kotlinlang.org/docs/basic-types.html) 66 * 67 * Non-basic types are not recommended, since deep copies are currently not supported. 68 * 69 * Example usage of a [Key] for a String value: 70 * ```kotlin 71 * object Name : Key<String> 72 * 73 * // Set Name 74 * mutableTypedMap[Name] = "First Last" 75 * typedMap = TypedMap(mutableTypedMap) 76 * 77 * // Get Name 78 * val myName = typedMap[Name] 79 * ``` 80 */ 81 interface Key<T> 82 83 /** 84 * A [TypedMap] is an immutable, type-safe map that allows for heterogeneously typed values. It 85 * copies in the current state of a provided [MutableTypedMap]. 86 */ 87 class TypedMap(mutableTypedMap: MutableTypedMap = MutableTypedMap()) { 88 private val map: MutableTypedMap = MutableTypedMap(mutableTypedMap.map.toMutableMap()) 89 90 /** Get object of type T or null if not present */ getnull91 operator fun <T> get(key: Key<T>): T? = map[key] 92 93 override fun equals(other: Any?): Boolean { 94 if (this === other) return true 95 if (other !is TypedMap) return false 96 if (map != other.map) return false 97 return true 98 } 99 hashCodenull100 override fun hashCode(): Int { 101 return map.hashCode() 102 } 103 } 104