diff --git a/doc/op.html b/doc/op.html
index 689f4ee..4007e72 100644
--- a/doc/op.html
+++ b/doc/op.html
@@ -102,7 +102,7 @@ function main() {
Types
+
+ Templates
+
+
@@ -142,7 +150,7 @@ function main() {
proc divide(a, b: int): OP[float] =
if b == 0:
- return fail(float, "Cannot divide by zero!")
+ return fail "Cannot divide by zero!"
else:
return ok a / b
@@ -153,7 +161,7 @@ function main() {
-OP[T] = object of RootObj
+
OP[T] = object
case isOk*: bool
of true:
val*: T
@@ -164,7 +172,9 @@ function main() {
-
-Object to wrap the result of an operation
- isOk: Indicates if the operation was successful
+Object to wrap the result of an operation.
+The type is discriminated by the isOK bool. So it is an compiler error to try to access the value without checking if the operation was successful.
+- isOk: Indicates if the operation was successful
- val: If successful, this will hold the real result value
- error: Otherwise this will hold an error message
@@ -177,14 +187,14 @@ Object to wrap the result of an operation- Procs
-proc ok[T](val: T): OP[T]
+proc ok[T](val: T): OP[T] {...}{.inline.}
-
Wraps the given value in a successful operation result.
-proc fail(op: OP; msg: string): OP
+proc fail(op: OP; msg: string): OP {...}{.inline.}
-
Will create a new operation result with the given error message. The type for the operation result is taken from the op argument.
@@ -197,26 +207,35 @@ Will create a new operation result with the given error message. The type for th
assert data.error == "Not implemented!"
-
-proc fail[T](msg: string): OP[T]
+
+proc fail(T: typedesc; msg: string): OP[T] {...}{.inline.}
-
Will create a new operation result with the given error message. The type for the operation result is given explicitly.
See Also:
-Examples:
-let res = fail[seq[float]] "Something is wrong!"
-assert res.isOk == false
-assert res.error == "Something is wrong!"
-
-proc fail(T: typedesc; msg: string): OP[T]
+
+
+
+
+
+
+template fail[T; ](O: type OP[T]; msg: string): O:type
-
-Alias for fail[T](string)
+
+
+
+
+template fail(msg: static[string]): auto
+-
+
+
@@ -229,7 +248,7 @@ Alias for fail[T](string)
- Made with Nim. Generated: 2020-07-02 16:37:38 UTC
+ Made with Nim. Generated: 2020-07-02 17:57:25 UTC
diff --git a/src/op.nim b/src/op.nim
index 67999a5..33c3135 100644
--- a/src/op.nim
+++ b/src/op.nim
@@ -17,7 +17,7 @@
## proc divide(a, b: int): OP[float] =
## ## This could fail
## if b == 0:
-## return fail(float, "Cannot divide by zero!")
+## return fail "Cannot divide by zero!"
## else:
## return ok a / b # Wrap the result
##
@@ -26,8 +26,12 @@
## assert r.error == "Cannot divide by zero!"
type
- OP*[T] = object of RootObj
- ## Object to wrap the result of an operation
+ OP*[T] = object
+ ## Object to wrap the result of an operation.
+ ##
+ ## The type is discriminated by the `isOK` bool.
+ ## So it is an compiler error to try to access the value without checking
+ ## if the operation was successful.
##
## - `isOk`: Indicates if the operation was successful
## - `val`: If successful, this will hold the real result value
@@ -38,11 +42,11 @@ type
of false:
error*: string
-proc ok*[T](val: T): OP[T] =
+proc ok*[T](val: T): OP[T] {.inline.} =
## Wraps the given value in a successful operation result.
OP[T](isOK: true, val: val)
-proc fail*(op: OP, msg: string): OP =
+proc fail*(op: OP, msg: string): OP {.inline.} =
## Will create a new operation result with the given error message.
## The type for the operation result is taken from the `op` argument.
runnableExamples:
@@ -54,20 +58,17 @@ proc fail*(op: OP, msg: string): OP =
assert data.error == "Not implemented!"
OP(isOK: false, error: msg)
-proc fail*[T](msg: string): OP[T] =
+proc fail*(T: typedesc, msg: string): OP[T] {.inline.} =
## Will create a new operation result with the given error message.
## The type for the operation result is given explicitly.
##
## **See Also:**
- ## - `fail proc
- ## <#fail,OP,string>`_
- runnableExamples:
- let res = fail[seq[float]] "Something is wrong!"
- assert res.isOk == false
- assert res.error == "Something is wrong!"
+ ## - `fail proc<#fail,OP,string>`_
+ ## - `fail template<#fail.t,static[string]>`_
OP[T](isOK: false, error: msg)
-proc fail*(T: typedesc, msg: string): OP[T] =
- ## Alias for `fail[T](string)<#fail,string>`_
- fail[T] msg
+template fail*[T](O: type OP[T], msg: string): O = O(isOK: false, error: msg)
+
+template fail*(msg: static[string]): auto = fail(typeof(result), msg)
+
diff --git a/tests/tests.nim b/tests/tests.nim
index faacbf6..0b031e2 100644
--- a/tests/tests.nim
+++ b/tests/tests.nim
@@ -3,66 +3,89 @@
import unittest
import op
-test "Check OK":
- let test = ok 1
- check test.isOk == true
+suite "Basic tests":
+ test "Check OK":
+ let test = ok 1
+ check test.isOk == true
-test "Check fail":
- let test = op.fail[int] "no data here"
- check test.isOk == false
+ test "Check fail":
+ let test = fail(void, "no data here")
+ check test.isOk == false
-test "Check proc results":
- proc createValue: OP[string] =
- let myString = "This is test code!"
- ok myString
- let data = createValue()
- check data.isOk
- check data.val == "This is test code!"
+ test "Check proc results":
+ proc createValue: OP[string] =
+ let myString = "This is test code!"
+ ok myString
+ let data = createValue()
+ check data.isOk
+ check data.val == "This is test code!"
-test "Check failing result proc":
- proc someProc(): OP[int] =
- result.fail "Not implemented!"
+ test "Check failing result proc":
+ proc someProc(): OP[int] =
+ result.fail "Not implemented!"
- let data = someProc()
- assert data.isOk == false
- assert data.error == "Not implemented!"
+ let data = someProc()
+ assert data.isOk == false
+ assert data.error == "Not implemented!"
-test "Check failing typedesc proc ":
- proc someProc(): OP[int] =
- fail(int, "Not implemented!")
+ test "Check failing typedesc proc ":
+ proc someProc(): OP[int] =
+ op.fail(int, "Not implemented!")
- let data = someProc()
- assert data.isOk == false
- assert data.error == "Not implemented!"
+ let data = someProc()
+ assert data.isOk == false
+ assert data.error == "Not implemented!"
-test "Check failing type param proc ":
- proc someProc(): OP[int] =
- op.fail[int]("Not implemented!")
+ test "Check failing type param proc ":
+ proc someProc(): OP[int] =
+ fail(int, "Not implemented!")
- let data = someProc()
- assert data.isOk == false
- assert data.error == "Not implemented!"
+ let data = someProc()
+ assert data.isOk == false
+ assert data.error == "Not implemented!"
-test "Check changing result":
- proc checker(): OP[int] =
- result = ok 42
- # something happend here
- result = result.fail "data got corrupted"
+ test "Check changing result":
+ proc checker(): OP[int] =
+ result = ok 42
+ # something happend here
+ result = result.fail "data got corrupted"
- let data = checker()
- check data.isOk == false
- check data.error == "data got corrupted"
+ let data = checker()
+ check data.isOk == false
+ check data.error == "data got corrupted"
-test "Check divider proc":
- proc divide(a, b: int): OP[float] =
- if b == 0:
- return fail(float, "Cannot divide by zero!")
- else:
- return ok a / b
+ test "Check divider proc":
+ proc divide(a, b: int): OP[float] =
+ if b == 0:
+ return fail(float, "Cannot divide by zero!")
+ else:
+ return ok a / b
- let
- a = 42
- b = 0
- let r = divide(a, b)
- check r.isOk == false
- check r.error == "Cannot divide by zero!"
\ No newline at end of file
+ let
+ a = 42
+ b = 0
+ let r = divide(a, b)
+ check r.isOk == false
+ check r.error == "Cannot divide by zero!"
+
+ test "Check implicit fail type":
+ proc divide(a, b: int): OP[float] =
+ if b == 0:
+ return fail "Cannot divide by zero!"
+ else:
+ return ok a / b
+
+ let r = divide(1, 0)
+ check r.isOk == false
+ check r.error == "Cannot divide by zero!"
+
+ test "Check type of impolicit fail":
+ proc divide(a, b: int): OP[float] =
+ if b == 0:
+ return fail "Cannot divide by zero!"
+ else:
+ return ok a / b
+
+ let r = divide(1, 0)
+ check r.isOk == false
+ check r.error == "Cannot divide by zero!"