Skip to content

Instantly share code, notes, and snippets.

@davethomas11
Created March 4, 2018 18:41
Show Gist options
  • Save davethomas11/4b747cadf5f692937fb9e3a6f2408e12 to your computer and use it in GitHub Desktop.
Save davethomas11/4b747cadf5f692937fb9e3a6f2408e12 to your computer and use it in GitHub Desktop.
You can use the in keyword in Kotlin with any class that implements operator contains
/**
* Using in keyword with other classes in Kotlin.
* ----------------------------------------------
*
*
* You can provide an operator contains function for a class so
* that you can use the in syntax in a when statement.
*/
/**
* For example if you for some reason wanted to do a when
* comparing against multiple regular expressions you could can add
* the contain operator function to the Regex class as so:
*/
operator fun Regex.contains(string: String) = this.find(string) != null
// This makes it possible to check for a [String] in a [Regex]
/**
* Then a function as such is valid as it checks for [String] in [Regex]
*/
fun platform(description: String) = when (description) {
in Regex(".*android.*", RegexOption.IGNORE_CASE) -> println("Platform is Android!")
in Regex(".*windows.*", RegexOption.IGNORE_CASE) -> println("Platform is Windows!")
in Regex(".*ios.*", RegexOption.IGNORE_CASE) -> println("Platform is iOS!")
else -> print("Don't know this platform??")
}
fun main(args: Array<String>) {
println("Checking platform of Mozilla/5.0 (Android; Mobile; rv:40.0) Gecko/40.0 Firefox/40.0")
platform("Mozilla/5.0 (Android; Mobile; rv:40.0) Gecko/40.0 Firefox/40.0")
println("Checking platform of Mozilla/5.0 (iPhone; CPU iPhone OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) FxiOS/1.0 Mobile/12F69 Safari/600.1.4")
platform("Mozilla/5.0 (iPhone; CPU iPhone OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) FxiOS/1.0 Mobile/12F69 Safari/600.1.4")
println("Checking platform of Mozilla/5.0 (Windows NT x.y; rv:10.0) Gecko/20100101 Firefox/10.0")
platform("Mozilla/5.0 (Windows NT x.y; rv:10.0) Gecko/20100101 Firefox/10.0")
}
/**
* Here is a more complex example from the MoshiPack source code:
*/
operator fun Array<MsgpackFormatType>.contains(value: Byte) = this.any { value in it }
data class MsgpackFormatType(val tag: Byte, val maxSize: Long, val isFix: Boolean = false) {
operator fun contains(value: Byte) = if (isFix) value in tag..tag+maxSize else value == tag
}
/**
* This allows checking if a Byte is contained by an Array of MsgpackFormatType.
* Since MsgpackFormatType is a complex data class, it also needs to check if the Byte
* belongs to it.
*
* This allows for the following when ->
*/
fun doProperByteAction(c: Byte) {
when (c) {
in MsgpackFormat.ARRAY -> println("Begin array!")
in MsgpackFormat.MAP -> println("Begin map!")
in MsgpackFormat.STR -> println("Begin string!")
else -> TODO()
}
}
object MsgpackFormat {
const val SIZE_8 = 255L
const val SIZE_16 = 65535L
const val SIZE_32 = 4294967295
val FIX_STR = MsgpackFormatType(0xa0.toByte(), 31, isFix = true)
val STR_8 = MsgpackFormatType(0xd9.toByte(), SIZE_8)
val STR_16 = MsgpackFormatType(0xda.toByte(), SIZE_16)
val STR_32 = MsgpackFormatType(0xdb.toByte(), SIZE_32)
val STR = arrayOf(FIX_STR, STR_8, STR_16, STR_32)
val FIX_ARRAY = MsgpackFormatType(0x90.toByte(), 15, isFix = true)
val ARRAY_16 = MsgpackFormatType(0xdc.toByte(), SIZE_16)
val ARRAY_32 = MsgpackFormatType(0xdd.toByte(), SIZE_32)
val ARRAY = arrayOf(FIX_ARRAY, ARRAY_16, ARRAY_32)
val FIX_MAP = MsgpackFormatType(0x80.toByte(), 15, isFix = true)
val MAP_16 = MsgpackFormatType(0xde.toByte(), SIZE_16)
val MAP_32 = MsgpackFormatType(0xdf.toByte(), SIZE_32)
val MAP = arrayOf(FIX_MAP, MAP_16, MAP_32)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment