/* * Quasseldroid - Quassel client for Android * * Copyright (c) 2020 Janne Mareike Koschinski * Copyright (c) 2020 The Quassel Project * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3 as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see <http://www.gnu.org/licenses/>. */ package de.kuschku.libquassel.protocol import de.kuschku.libquassel.protocol.primitive.serializer.Serializer sealed class QVariant<T> constructor( val data: T?, val type: QtType, val serializer: Serializer<T> ) { class Typed<T> internal constructor(data: T?, type: QtType, serializer: Serializer<T>) : QVariant<T>(data, type, serializer) { override fun toString() = "QVariant.Typed(${type.serializableName}, $data)" override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is Typed<*>) return false if (data != other.data) return false if (type != other.type) return false return true } override fun hashCode(): Int { var result = data?.hashCode() ?: 0 result = 31 * result + type.hashCode() return result } } class Custom<T> internal constructor( data: T?, val qtype: QuasselType, serializer: Serializer<T> ) : QVariant<T>(data, qtype.type, serializer) { override fun toString() = "QVariant.Custom($qtype, $data)" override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is Custom<*>) return false if (data != other.data) return false if (qtype != other.qtype) return false return true } override fun hashCode(): Int { var result = data?.hashCode() ?: 0 result = 31 * result + qtype.hashCode() return result } } fun or(defValue: T): T { return data ?: defValue } companion object { @Suppress("UNCHECKED_CAST") fun <T> of(data: T?, type: QtType): QVariant<T> = Typed(data, type, type.serializer as Serializer<T>) @Suppress("UNCHECKED_CAST") fun <T> of(data: T?, type: QuasselType) = Custom(data, type, type.serializer as Serializer<T>) } } inline fun <reified T> qVariant(data: T, type: QtType): QVariant<T> = QVariant.of(data, type) inline fun <reified T> qVariant(data: T, type: QuasselType): QVariant<T> = QVariant.of(data, type) inline fun <reified U> QVariant_?.value(): U? = this?.value<U?>(null) inline fun <reified U> QVariant_?.value(defValue: U): U = this?.data as? U ?: defValue inline fun <reified U> QVariant_?.valueOr(f: () -> U): U = this?.data as? U ?: f() inline fun <reified U> QVariant_?.valueOrThrow(e: Throwable = ClassCastException("Could not obtain a ${U::class.java.canonicalName} from $this")): U = this?.data as? U ?: throw e inline fun <reified U> QVariant_?.valueOrThrow(e: () -> Throwable): U = this?.data as? U ?: throw e()