From 8614d0f2c3ecaf31586293e44f9a3052a69357ec Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Thu, 11 Feb 2021 23:37:14 +0100
Subject: [PATCH] Reorganize code and add readme

---
 README.md                                     | 50 +++++++++++
 src/main/kotlin/de/justjanne/bitflags/of.kt   | 77 ++++++++++++++++
 .../kotlin/de/justjanne/bitflags/toFlag.kt    | 90 -------------------
 3 files changed, 127 insertions(+), 90 deletions(-)
 create mode 100644 README.md
 delete mode 100644 src/main/kotlin/de/justjanne/bitflags/toFlag.kt

diff --git a/README.md b/README.md
new file mode 100644
index 0000000..00bc3eb
--- /dev/null
+++ b/README.md
@@ -0,0 +1,50 @@
+# Kotlin Bitflags
+
+Kotlin-Bitflags is a utility library to simplify implementing bitflags in Kotlin. It integrates with Kotlin unsigned 
+types and Java Enumsets. This especially useful when interacting with binary protocols from Kotlin.
+
+## Using Kotlin-Bitflags
+
+After adding this module to your dependencies, you'll have to implement the related interfaces in your classes:
+
+```kotlin
+enum class MessageFlag(
+  override val value: UInt,
+) : Flag<UInt> {
+  Self(0x01u),
+  Highlight(0x02u),
+  Redirected(0x04u),
+  ServerMsg(0x08u),
+  Backlog(0x80u);
+
+  companion object : Flags<UInt, MessageFlag> {
+    override val all: Set<MessageFlag> = values().toEnumSet()
+  }
+}
+```
+
+This allows you to then use this elsewhere to e.g initialize a field from discrete values
+```kotlin
+// Construct from varargs or an array
+val field = MessageFlag.of(MessageFlag.Self, MessageFlag.Highlight)
+
+val values = listOf(MessageFlag.Self, MessageFlag.Highlight)
+// Or from a collection
+val field = MessageFlag.of(values)
+// Or use the to helper
+val field = values.toEnumSet()
+```
+
+You can also convert such a field into the raw binary value easily
+```kotlin
+// Returns in this case UInt
+field.toBits()
+```
+
+Additional utility functions are available:
+```kotlin
+// Empty field
+MessageFlag.none()
+// Get all non-null values
+MessageFlag.validValues()
+```
diff --git a/src/main/kotlin/de/justjanne/bitflags/of.kt b/src/main/kotlin/de/justjanne/bitflags/of.kt
index 047f12f..e1573d9 100644
--- a/src/main/kotlin/de/justjanne/bitflags/of.kt
+++ b/src/main/kotlin/de/justjanne/bitflags/of.kt
@@ -11,6 +11,7 @@
 package de.justjanne.bitflags
 
 import java.util.EnumSet
+import kotlin.experimental.and
 
 /**
  * Construct a bitfield out of discrete flags
@@ -25,3 +26,79 @@ inline fun <reified T> Flags<*, T>.of(vararg values: T): EnumSet<T>
  */
 inline fun <reified T> Flags<*, T>.of(values: Collection<T>): EnumSet<T>
   where T : Flag<*>, T : Enum<T> = values.toEnumSet()
+
+/**
+ * Construct a bitfield out of a binary value
+ * @return bitfield
+ */
+inline fun <reified T> Flags<Byte, T>.of(value: Byte?): EnumSet<T> where T : Flag<Byte>, T : Enum<T> {
+  if (value == null) return emptyList<T>().toEnumSet()
+  return all.filter { (value and it.value) != 0.toByte() }.toEnumSet()
+}
+
+/**
+ * Construct a bitfield out of a binary value
+ * @return bitfield
+ */
+@ExperimentalUnsignedTypes
+inline fun <reified T> Flags<UByte, T>.of(value: UByte?): EnumSet<T> where T : Flag<UByte>, T : Enum<T> {
+  if (value == null) return emptyList<T>().toEnumSet()
+  return all.filter { (value and it.value) != 0.toUByte() }.toEnumSet()
+}
+
+/**
+ * Construct a bitfield out of a binary value
+ * @return bitfield
+ */
+inline fun <reified T> Flags<Short, T>.of(value: Short?): EnumSet<T> where T : Flag<Short>, T : Enum<T> {
+  if (value == null) return emptyList<T>().toEnumSet()
+  return all.filter { (value and it.value) != 0.toShort() }.toEnumSet()
+}
+
+/**
+ * Construct a bitfield out of a binary value
+ * @return bitfield
+ */
+@ExperimentalUnsignedTypes
+inline fun <reified T> Flags<UShort, T>.of(value: UShort?): EnumSet<T> where T : Flag<UShort>, T : Enum<T> {
+  if (value == null) return emptyList<T>().toEnumSet()
+  return all.filter { (value and it.value) != 0.toUShort() }.toEnumSet()
+}
+
+/**
+ * Construct a bitfield out of a binary value
+ * @return bitfield
+ */
+inline fun <reified T> Flags<Int, T>.of(value: Int?): EnumSet<T> where T : Flag<Int>, T : Enum<T> {
+  if (value == null) return emptyList<T>().toEnumSet()
+  return all.filter { (value and it.value) != 0 }.toEnumSet()
+}
+
+/**
+ * Construct a bitfield out of a binary value
+ * @return bitfield
+ */
+@ExperimentalUnsignedTypes
+inline fun <reified T> Flags<UInt, T>.of(value: UInt?): EnumSet<T> where T : Flag<UInt>, T : Enum<T> {
+  if (value == null) return emptyList<T>().toEnumSet()
+  return all.filter { (value and it.value) != 0u }.toEnumSet()
+}
+
+/**
+ * Construct a bitfield out of a binary value
+ * @return bitfield
+ */
+inline fun <reified T> Flags<Long, T>.of(value: Long?): EnumSet<T> where T : Flag<Long>, T : Enum<T> {
+  if (value == null) return emptyList<T>().toEnumSet()
+  return all.filter { (value and it.value) != 0L }.toEnumSet()
+}
+
+/**
+ * Construct a bitfield out of a binary value
+ * @return bitfield
+ */
+@ExperimentalUnsignedTypes
+inline fun <reified T> Flags<ULong, T>.of(value: ULong?): EnumSet<T> where T : Flag<ULong>, T : Enum<T> {
+  if (value == null) return emptyList<T>().toEnumSet()
+  return all.filter { (value and it.value) != 0uL }.toEnumSet()
+}
diff --git a/src/main/kotlin/de/justjanne/bitflags/toFlag.kt b/src/main/kotlin/de/justjanne/bitflags/toFlag.kt
deleted file mode 100644
index 98cb909..0000000
--- a/src/main/kotlin/de/justjanne/bitflags/toFlag.kt
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Kotlin Bitflags
- *
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.bitflags
-
-import java.util.EnumSet
-import kotlin.experimental.and
-
-/**
- * Construct a bitfield out of a binary value
- * @return bitfield
- */
-inline fun <reified T> Flags<Byte, T>.of(value: Byte?): EnumSet<T> where T : Flag<Byte>, T : Enum<T> {
-  if (value == null) return emptyList<T>().toEnumSet()
-  return all.filter { (value and it.value) != 0.toByte() }.toEnumSet()
-}
-
-/**
- * Construct a bitfield out of a binary value
- * @return bitfield
- */
-@ExperimentalUnsignedTypes
-inline fun <reified T> Flags<UByte, T>.of(value: UByte?): EnumSet<T> where T : Flag<UByte>, T : Enum<T> {
-  if (value == null) return emptyList<T>().toEnumSet()
-  return all.filter { (value and it.value) != 0.toUByte() }.toEnumSet()
-}
-
-/**
- * Construct a bitfield out of a binary value
- * @return bitfield
- */
-inline fun <reified T> Flags<Short, T>.of(value: Short?): EnumSet<T> where T : Flag<Short>, T : Enum<T> {
-  if (value == null) return emptyList<T>().toEnumSet()
-  return all.filter { (value and it.value) != 0.toShort() }.toEnumSet()
-}
-
-/**
- * Construct a bitfield out of a binary value
- * @return bitfield
- */
-@ExperimentalUnsignedTypes
-inline fun <reified T> Flags<UShort, T>.of(value: UShort?): EnumSet<T> where T : Flag<UShort>, T : Enum<T> {
-  if (value == null) return emptyList<T>().toEnumSet()
-  return all.filter { (value and it.value) != 0.toUShort() }.toEnumSet()
-}
-
-/**
- * Construct a bitfield out of a binary value
- * @return bitfield
- */
-inline fun <reified T> Flags<Int, T>.of(value: Int?): EnumSet<T> where T : Flag<Int>, T : Enum<T> {
-  if (value == null) return emptyList<T>().toEnumSet()
-  return all.filter { (value and it.value) != 0 }.toEnumSet()
-}
-
-/**
- * Construct a bitfield out of a binary value
- * @return bitfield
- */
-@ExperimentalUnsignedTypes
-inline fun <reified T> Flags<UInt, T>.of(value: UInt?): EnumSet<T> where T : Flag<UInt>, T : Enum<T> {
-  if (value == null) return emptyList<T>().toEnumSet()
-  return all.filter { (value and it.value) != 0u }.toEnumSet()
-}
-
-/**
- * Construct a bitfield out of a binary value
- * @return bitfield
- */
-inline fun <reified T> Flags<Long, T>.of(value: Long?): EnumSet<T> where T : Flag<Long>, T : Enum<T> {
-  if (value == null) return emptyList<T>().toEnumSet()
-  return all.filter { (value and it.value) != 0L }.toEnumSet()
-}
-
-/**
- * Construct a bitfield out of a binary value
- * @return bitfield
- */
-@ExperimentalUnsignedTypes
-inline fun <reified T> Flags<ULong, T>.of(value: ULong?): EnumSet<T> where T : Flag<ULong>, T : Enum<T> {
-  if (value == null) return emptyList<T>().toEnumSet()
-  return all.filter { (value and it.value) != 0uL }.toEnumSet()
-}
-- 
GitLab