diff --git a/README.md b/README.md
index 0fc6396..f884c4a 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@ repositories {
}
dependencies {
- implementation("me.alex_s168:blitz:0.14")
+ implementation("me.alex_s168:blitz:0.15")
}
```
diff --git a/build.gradle.kts b/build.gradle.kts
index cd3e3f7..1290dbb 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -5,7 +5,7 @@ plugins {
}
group = "me.alex_s168"
-version = "0.14"
+version = "0.15"
repositories {
mavenCentral()
diff --git a/src/main/kotlin/blitz/Either.kt b/src/main/kotlin/blitz/Either.kt
index 56d27b1..dbe9b8c 100644
--- a/src/main/kotlin/blitz/Either.kt
+++ b/src/main/kotlin/blitz/Either.kt
@@ -4,6 +4,9 @@ class Either private constructor(
private val a: Obj?,
private val b: Obj?
) {
+ override fun equals(other: Any?): Boolean =
+ other is Either<*, *> && other.a == a && other.b == b
+
fun getAOrNull(): A? =
a?.v
@@ -41,6 +44,12 @@ class Either private constructor(
if (isA) "Either(${a!!.v})"
else "Either(${b!!.v})"
+ override fun hashCode(): Int {
+ var result = a?.hashCode() ?: 0
+ result = 31 * result + (b?.hashCode() ?: 0)
+ return result
+ }
+
companion object {
fun ofA(a: A): Either =
Either(Obj.of(a), null)
@@ -51,4 +60,28 @@ class Either private constructor(
}
fun Either.flatten(): R where A: R, B: R =
- getAOrNull() ?: getB()
\ No newline at end of file
+ getAOrNull() ?: getB()
+
+fun Either>.mapBA(fn: (BA) -> BAN): Either> =
+ mapB { it.mapA(fn) }
+
+fun Either>.mapBB(fn: (BB) -> BBN): Either> =
+ mapB { it.mapB(fn) }
+
+fun Either, B>.mapAA(fn: (AA) -> AAN): Either, B> =
+ mapA { it.mapA(fn) }
+
+fun Either, B>.mapAB(fn: (AB) -> ABN): Either, B> =
+ mapA { it.mapB(fn) }
+
+fun Either, B>.getAAOrNull(): AA? =
+ getAOrNull()?.getAOrNull()
+
+fun Either, B>.getABOrNull(): AB? =
+ getAOrNull()?.getBOrNull()
+
+fun Either>.getBAOrNull(): BA? =
+ getBOrNull()?.getAOrNull()
+
+fun Either>.getBBOrNull(): BB? =
+ getBOrNull()?.getBOrNull()
\ No newline at end of file
diff --git a/src/main/kotlin/blitz/Obj.kt b/src/main/kotlin/blitz/Obj.kt
index d4dea17..425e742 100644
--- a/src/main/kotlin/blitz/Obj.kt
+++ b/src/main/kotlin/blitz/Obj.kt
@@ -12,6 +12,11 @@ interface Obj {
override fun toString(): String =
"Obj($v)"
+
+ override fun equals(other: Any?): Boolean =
+ (other is Obj<*>) && v == other.v
+
+ override fun hashCode(): Int = v.hashCode()
}
}
}
@@ -32,6 +37,11 @@ interface MutObj {
override fun toString(): String =
"MutObj($v)"
+
+ override fun equals(other: Any?): Boolean =
+ (other is Obj<*>) && v == other.v
+
+ override fun hashCode(): Int = v.hashCode()
}
fun mutex(v: T): MutObj =
@@ -43,6 +53,11 @@ interface MutObj {
override fun toString(): String =
"MutMutexObj($v)"
+
+ override fun equals(other: Any?): Boolean =
+ (other is Obj<*>) && v == other.v
+
+ override fun hashCode(): Int = v.hashCode()
}
}
}
\ No newline at end of file
diff --git a/src/main/kotlin/blitz/collections/ListOps.kt b/src/main/kotlin/blitz/collections/ListOps.kt
index 6cd58dd..376d792 100644
--- a/src/main/kotlin/blitz/collections/ListOps.kt
+++ b/src/main/kotlin/blitz/collections/ListOps.kt
@@ -24,4 +24,7 @@ fun MutableList.removeLastInto(count: Int, dest: MutableList = mutable
dest.add(removeLast())
}
return dest
-}
\ No newline at end of file
+}
+
+fun MutableList.addFront(value: T) =
+ add(0, value)
\ No newline at end of file
diff --git a/src/main/kotlin/blitz/str/Escape.kt b/src/main/kotlin/blitz/str/Escape.kt
new file mode 100644
index 0000000..f4ca7b1
--- /dev/null
+++ b/src/main/kotlin/blitz/str/Escape.kt
@@ -0,0 +1,28 @@
+package blitz.str
+
+fun unescape(str: String): String {
+ val out = StringBuilder()
+ var escaped = false
+
+ for (char in str) {
+ if (escaped) {
+ escaped = false
+ val e = when (char) {
+ 'n' -> '\n'
+ 'r' -> '\r'
+ 't' -> '\t'
+ '\\' -> '\\'
+ '"' -> '"'
+ '\'' -> '\''
+ else -> error("Unexpected character '$char'")
+ }
+ out.append(e)
+ } else if (char == '\\') {
+ escaped = true
+ } else {
+ out.append(char)
+ }
+ }
+
+ return out.toString()
+}
\ No newline at end of file