From 34ee44b532c5b92b258e471a3a30b58f857aa21d Mon Sep 17 00:00:00 2001
From: Mike Hearn <mike@r3cev.com>
Date: Thu, 8 Sep 2016 13:08:45 +0200
Subject: [PATCH 1/2] Minor: move ErrorOr into the core module and tweak its
 API a bit. Add a Path div operator.

---
 .../kotlin/com/r3corda/client/mock/ErrorOr.kt | 40 -----------------
 .../com/r3corda/client/mock/Generator.kt      | 23 ++++++----
 .../src/main/kotlin/com/r3corda/core/Utils.kt | 43 ++++++++++++++++++-
 3 files changed, 56 insertions(+), 50 deletions(-)
 delete mode 100644 client/src/main/kotlin/com/r3corda/client/mock/ErrorOr.kt

diff --git a/client/src/main/kotlin/com/r3corda/client/mock/ErrorOr.kt b/client/src/main/kotlin/com/r3corda/client/mock/ErrorOr.kt
deleted file mode 100644
index 1dee4278be..0000000000
--- a/client/src/main/kotlin/com/r3corda/client/mock/ErrorOr.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.r3corda.client.mock
-
-class ErrorOr<out A> private constructor(
-        val value: A?,
-        val error: Exception?
-) {
-    constructor(value: A): this(value, null)
-    constructor(error: Exception): this(null, error)
-
-    fun <T> match(onValue: (A) -> T, onError: (Exception) -> T): T {
-        if (value != null) {
-            return onValue(value)
-        } else {
-            return onError(error!!)
-        }
-    }
-
-    fun getValueOrThrow(): A {
-        if (value != null) {
-            return value
-        } else {
-            throw error!!
-        }
-    }
-
-    // Functor
-    fun <B> map(function: (A) -> B): ErrorOr<B> {
-        return ErrorOr(value?.let(function), error)
-    }
-
-    // Applicative
-    fun <B, C> combine(other: ErrorOr<B>, function: (A, B) -> C): ErrorOr<C> {
-        return ErrorOr(value?.let { a -> other.value?.let { b -> function(a, b) } }, error ?: other.error)
-    }
-
-    // Monad
-    fun <B> bind(function: (A) -> ErrorOr<B>): ErrorOr<B> {
-        return value?.let(function) ?: ErrorOr<B>(error!!)
-    }
-}
diff --git a/client/src/main/kotlin/com/r3corda/client/mock/Generator.kt b/client/src/main/kotlin/com/r3corda/client/mock/Generator.kt
index 6991dec7a5..1d998c442d 100644
--- a/client/src/main/kotlin/com/r3corda/client/mock/Generator.kt
+++ b/client/src/main/kotlin/com/r3corda/client/mock/Generator.kt
@@ -1,5 +1,7 @@
 package com.r3corda.client.mock
 
+import com.r3corda.client.mock.Generator.Companion.choice
+import com.r3corda.core.ErrorOr
 import java.util.*
 
 /**
@@ -54,7 +56,7 @@ class Generator<out A>(val generate: (Random) -> ErrorOr<A>) {
     companion object {
         fun <A> pure(value: A) = Generator { ErrorOr(value) }
         fun <A> impure(valueClosure: () -> A) = Generator { ErrorOr(valueClosure()) }
-        fun <A> fail(error: Exception) = Generator<A> { ErrorOr(error) }
+        fun <A> fail(error: Exception) = Generator<A> { ErrorOr.of(error) }
 
         // Alternative
         fun <A> choice(generators: List<Generator<A>>) = intRange(0, generators.size - 1).bind { generators[it] }
@@ -85,10 +87,11 @@ class Generator<out A>(val generate: (Random) -> ErrorOr<A>) {
             val result = mutableListOf<A>()
             for (generator in generators) {
                 val element = generator.generate(it)
-                if (element.value != null) {
-                    result.add(element.value)
+                val v = element.value
+                if (v != null) {
+                    result.add(v)
                 } else {
-                    return@Generator ErrorOr(element.error!!)
+                    return@Generator ErrorOr.of(element.error!!)
                 }
             }
             ErrorOr(result)
@@ -99,11 +102,12 @@ class Generator<out A>(val generate: (Random) -> ErrorOr<A>) {
 fun <A> Generator.Companion.oneOf(list: List<A>) = intRange(0, list.size - 1).map { list[it] }
 
 fun <A> Generator<A>.generateOrFail(random: Random, numberOfTries: Int = 1): A {
-    var error: Exception? = null
+    var error: Throwable? = null
     for (i in 0 .. numberOfTries - 1) {
         val result = generate(random)
-        if (result.value != null) {
-            return result.value
+        val v = result.value
+        if (v != null) {
+            return v
         } else {
             error = result.error
         }
@@ -146,8 +150,9 @@ fun <A> Generator.Companion.replicatePoisson(meanSize: Double, generator: Genera
                 ErrorOr(Unit)
             }
         }
-        if (errorOr.error != null) {
-            return@Generator ErrorOr(errorOr.error)
+        val e = errorOr.error
+        if (e != null) {
+            return@Generator ErrorOr.of(e)
         }
     }
     ErrorOr(result)
diff --git a/core/src/main/kotlin/com/r3corda/core/Utils.kt b/core/src/main/kotlin/com/r3corda/core/Utils.kt
index 33eecc541c..67a3eb4ed8 100644
--- a/core/src/main/kotlin/com/r3corda/core/Utils.kt
+++ b/core/src/main/kotlin/com/r3corda/core/Utils.kt
@@ -218,4 +218,45 @@ fun extractZipFile(zipPath: Path, toPath: Path) {
 
 // TODO: Generic csv printing utility for clases.
 
-val Throwable.rootCause: Throwable get() = Throwables.getRootCause(this)
\ No newline at end of file
+val Throwable.rootCause: Throwable get() = Throwables.getRootCause(this)
+
+/** Allows you to write code like: Paths.get("someDir") / "subdir" / "filename" but using the Paths API to avoid platform separator problems. */
+operator fun Path.div(other: String): Path = resolve(other)
+
+/** Representation of an operation that may have thrown an error. */
+data class ErrorOr<out A> private constructor(val value: A?, val error: Throwable?) {
+    constructor(value: A) : this(value, null)
+
+    companion object {
+        /** Runs the given lambda and wraps the result. */
+        inline fun <T> catch(body: () -> T): ErrorOr<T> = try { ErrorOr(body()) } catch (t: Throwable) { ErrorOr.of(t) }
+        fun of(t: Throwable) = ErrorOr(null, t)
+    }
+
+    fun <T> match(onValue: (A) -> T, onError: (Throwable) -> T): T {
+        if (value != null) {
+            return onValue(value)
+        } else {
+            return onError(error!!)
+        }
+    }
+
+    fun getOrThrow(): A {
+        if (value != null) {
+            return value
+        } else {
+            throw error!!
+        }
+    }
+
+    // Functor
+    fun <B> map(function: (A) -> B) = ErrorOr(value?.let(function), error)
+
+    // Applicative
+    fun <B, C> combine(other: ErrorOr<B>, function: (A, B) -> C): ErrorOr<C> {
+        return ErrorOr(value?.let { a -> other.value?.let { b -> function(a, b) } }, error ?: other.error)
+    }
+
+    // Monad
+    fun <B> bind(function: (A) -> ErrorOr<B>) = value?.let(function) ?: ErrorOr.of(error!!)
+}
\ No newline at end of file

From af72978acef92fe528d6238cca262d40f2a5e4fa Mon Sep 17 00:00:00 2001
From: Mike Hearn <mike@r3cev.com>
Date: Thu, 8 Sep 2016 14:41:17 +0200
Subject: [PATCH 2/2] Remove redundant import.

---
 client/src/main/kotlin/com/r3corda/client/mock/Generator.kt | 1 -
 1 file changed, 1 deletion(-)

diff --git a/client/src/main/kotlin/com/r3corda/client/mock/Generator.kt b/client/src/main/kotlin/com/r3corda/client/mock/Generator.kt
index 1d998c442d..1ef0f64ae9 100644
--- a/client/src/main/kotlin/com/r3corda/client/mock/Generator.kt
+++ b/client/src/main/kotlin/com/r3corda/client/mock/Generator.kt
@@ -1,6 +1,5 @@
 package com.r3corda.client.mock
 
-import com.r3corda.client.mock.Generator.Companion.choice
 import com.r3corda.core.ErrorOr
 import java.util.*