Add fail templates

This commit is contained in:
2020-07-02 19:59:01 +02:00
parent cd80913346
commit 8f27c5e552
3 changed files with 127 additions and 84 deletions

View File

@@ -102,7 +102,7 @@ function main() {
<a class="reference reference-toplevel" href="#7" id="57">Types</a>
<ul class="simple simple-toc-section">
<li><a class="reference" href="#OP"
title="OP[T] = object of RootObj
title="OP[T] = object
case isOk*: bool
of true:
val*: T
@@ -119,13 +119,21 @@ function main() {
title="ok[T](val: T): OP[T]"><wbr />ok<span class="attachedType">OP</span></a></li>
<li><a class="reference" href="#fail%2COP%2Cstring"
title="fail(op: OP; msg: string): OP"><wbr />fail<span class="attachedType">OP</span></a></li>
<li><a class="reference" href="#fail%2Cstring"
title="fail[T](msg: string): OP[T]"><wbr />fail<span class="attachedType">OP</span></a></li>
<li><a class="reference" href="#fail%2Ctypedesc%2Cstring"
title="fail(T: typedesc; msg: string): OP[T]"><wbr />fail<span class="attachedType">OP</span></a></li>
</ul>
</li>
<li>
<a class="reference reference-toplevel" href="#18" id="68">Templates</a>
<ul class="simple simple-toc-section">
<li><a class="reference" href="#fail.t%2C%2Cstring"
title="fail[T; ](O: type OP[T]; msg: string): O:type"><wbr />fail<span class="attachedType">OP</span></a></li>
<li><a class="reference" href="#fail.t%2Cstatic%5Bstring%5D"
title="fail(msg: static[string]): auto"><wbr />fail<span class="attachedType"></span></a></li>
</ul>
</li>
</ul>
@@ -142,7 +150,7 @@ function main() {
<h1><a class="toc-backref" id="basic-usage" href="#basic-usage">Basic Usage</a></h1><pre class="listing"><span class="Keyword">proc</span> <span class="Identifier">divide</span><span class="Punctuation">(</span><span class="Identifier">a</span><span class="Punctuation">,</span> <span class="Identifier">b</span><span class="Punctuation">:</span> <span class="Identifier">int</span><span class="Punctuation">)</span><span class="Punctuation">:</span> <span class="Identifier">OP</span><span class="Punctuation">[</span><span class="Identifier">float</span><span class="Punctuation">]</span> <span class="Operator">=</span>
<span class="Comment">## This could fail</span>
<span class="Keyword">if</span> <span class="Identifier">b</span> <span class="Operator">==</span> <span class="DecNumber">0</span><span class="Punctuation">:</span>
<span class="Keyword">return</span> <span class="Identifier">fail</span><span class="Punctuation">(</span><span class="Identifier">float</span><span class="Punctuation">,</span> <span class="StringLit">&quot;Cannot divide by zero!&quot;</span><span class="Punctuation">)</span>
<span class="Keyword">return</span> <span class="Identifier">fail</span> <span class="StringLit">&quot;Cannot divide by zero!&quot;</span>
<span class="Keyword">else</span><span class="Punctuation">:</span>
<span class="Keyword">return</span> <span class="Identifier">ok</span> <span class="Identifier">a</span> <span class="Operator">/</span> <span class="Identifier">b</span> <span class="Comment"># Wrap the result</span>
@@ -153,7 +161,7 @@ function main() {
<h1><a class="toc-backref" href="#7">Types</a></h1>
<dl class="item">
<a id="OP"></a>
<dt><pre><a href="op.html#OP"><span class="Identifier">OP</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span> <span class="Other">=</span> <span class="Keyword">object</span> <span class="Keyword">of</span> <span class="Identifier">RootObj</span>
<dt><pre><a href="op.html#OP"><span class="Identifier">OP</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span> <span class="Other">=</span> <span class="Keyword">object</span>
<span class="Keyword">case</span> <span class="Identifier">isOk</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">bool</span>
<span class="Keyword">of</span> <span class="Identifier">true</span><span class="Other">:</span>
<span class="Identifier">val</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">T</span>
@@ -164,7 +172,9 @@ function main() {
</pre></dt>
<dd>
Object to wrap the result of an operation<ul class="simple"><li><tt class="docutils literal"><span class="pre">isOk</span></tt>: Indicates if the operation was successful</li>
<p>Object to wrap the result of an operation.</p>
<p>The type is discriminated by the <tt class="docutils literal"><span class="pre">isOK</span></tt> bool. So it is an compiler error to try to access the value without checking if the operation was successful.</p>
<ul class="simple"><li><tt class="docutils literal"><span class="pre">isOk</span></tt>: Indicates if the operation was successful</li>
<li><tt class="docutils literal"><span class="pre">val</span></tt>: If successful, this will hold the real result value</li>
<li><tt class="docutils literal"><span class="pre">error</span></tt>: Otherwise this will hold an error message</li>
</ul>
@@ -177,14 +187,14 @@ Object to wrap the result of an operation<ul class="simple"><li><tt class="docut
<h1><a class="toc-backref" href="#12">Procs</a></h1>
<dl class="item">
<a id="ok,T"></a>
<dt><pre><span class="Keyword">proc</span> <a href="#ok%2CT"><span class="Identifier">ok</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span><span class="Other">(</span><span class="Identifier">val</span><span class="Other">:</span> <span class="Identifier">T</span><span class="Other">)</span><span class="Other">:</span> <a href="op.html#OP"><span class="Identifier">OP</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span></pre></dt>
<dt><pre><span class="Keyword">proc</span> <a href="#ok%2CT"><span class="Identifier">ok</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span><span class="Other">(</span><span class="Identifier">val</span><span class="Other">:</span> <span class="Identifier">T</span><span class="Other">)</span><span class="Other">:</span> <a href="op.html#OP"><span class="Identifier">OP</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span></span><span class="Other">.}</span></span></pre></dt>
<dd>
Wraps the given value in a successful operation result.
</dd>
<a id="fail,OP,string"></a>
<dt><pre><span class="Keyword">proc</span> <a href="#fail%2COP%2Cstring"><span class="Identifier">fail</span></a><span class="Other">(</span><span class="Identifier">op</span><span class="Other">:</span> <a href="op.html#OP"><span class="Identifier">OP</span></a><span class="Other">;</span> <span class="Identifier">msg</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">OP</span></pre></dt>
<dt><pre><span class="Keyword">proc</span> <a href="#fail%2COP%2Cstring"><span class="Identifier">fail</span></a><span class="Other">(</span><span class="Identifier">op</span><span class="Other">:</span> <a href="op.html#OP"><span class="Identifier">OP</span></a><span class="Other">;</span> <span class="Identifier">msg</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">OP</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span></span><span class="Other">.}</span></span></pre></dt>
<dd>
Will create a new operation result with the given error message. The type for the operation result is taken from the <tt class="docutils literal"><span class="pre">op</span></tt> argument.
@@ -197,26 +207,35 @@ Will create a new operation result with the given error message. The type for th
<span class="Identifier">assert</span> <span class="Identifier">data</span><span class="Other">.</span><span class="Identifier">error</span> <span class="Operator">==</span> <span class="StringLit">&quot;Not implemented!&quot;</span></pre>
</dd>
<a id="fail,string"></a>
<dt><pre><span class="Keyword">proc</span> <a href="#fail%2Cstring"><span class="Identifier">fail</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span><span class="Other">(</span><span class="Identifier">msg</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">)</span><span class="Other">:</span> <a href="op.html#OP"><span class="Identifier">OP</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span></pre></dt>
<a id="fail,typedesc,string"></a>
<dt><pre><span class="Keyword">proc</span> <a href="#fail%2Ctypedesc%2Cstring"><span class="Identifier">fail</span></a><span class="Other">(</span><span class="Identifier">T</span><span class="Other">:</span> <span class="Identifier">typedesc</span><span class="Other">;</span> <span class="Identifier">msg</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">)</span><span class="Other">:</span> <a href="op.html#OP"><span class="Identifier">OP</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span></span><span class="Other">.}</span></span></pre></dt>
<dd>
<p>Will create a new operation result with the given error message. The type for the operation result is given explicitly.</p>
<p><strong>See Also:</strong></p>
<ul class="simple"><li><a class="reference external" href="#fail,OP,string">fail proc</a></li>
<li><a class="reference external" href="#fail.t,static[string]">fail template</a></li>
</ul>
<p><strong class="examples_text">Examples:</strong></p>
<pre class="listing"><span class="Keyword">let</span> <span class="Identifier">res</span> <span class="Other">=</span> <span class="Identifier">fail</span><span class="Other">[</span><span class="Identifier">seq</span><span class="Other">[</span><span class="Identifier">float</span><span class="Other">]</span><span class="Other">]</span> <span class="StringLit">&quot;Something is wrong!&quot;</span>
<span class="Identifier">assert</span> <span class="Identifier">res</span><span class="Other">.</span><span class="Identifier">isOk</span> <span class="Operator">==</span> <span class="Identifier">false</span>
<span class="Identifier">assert</span> <span class="Identifier">res</span><span class="Other">.</span><span class="Identifier">error</span> <span class="Operator">==</span> <span class="StringLit">&quot;Something is wrong!&quot;</span></pre>
</dd>
<a id="fail,typedesc,string"></a>
<dt><pre><span class="Keyword">proc</span> <a href="#fail%2Ctypedesc%2Cstring"><span class="Identifier">fail</span></a><span class="Other">(</span><span class="Identifier">T</span><span class="Other">:</span> <span class="Identifier">typedesc</span><span class="Other">;</span> <span class="Identifier">msg</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">)</span><span class="Other">:</span> <a href="op.html#OP"><span class="Identifier">OP</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span></pre></dt>
</dl></div>
<div class="section" id="18">
<h1><a class="toc-backref" href="#18">Templates</a></h1>
<dl class="item">
<a id="fail.t,,string"></a>
<dt><pre><span class="Keyword">template</span> <a href="#fail.t%2C%2Cstring"><span class="Identifier">fail</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">;</span> <span class="Other">]</span><span class="Other">(</span><span class="Identifier">O</span><span class="Other">:</span> <span class="Keyword">type</span> <a href="op.html#OP"><span class="Identifier">OP</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span><span class="Other">;</span> <span class="Identifier">msg</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">O:type</span></pre></dt>
<dd>
Alias for <a class="reference external" href="#fail,string">fail[T](string)</a>
</dd>
<a id="fail.t,static[string]"></a>
<dt><pre><span class="Keyword">template</span> <a href="#fail.t%2Cstatic%5Bstring%5D"><span class="Identifier">fail</span></a><span class="Other">(</span><span class="Identifier">msg</span><span class="Other">:</span> <span class="Identifier">static</span><span class="Other">[</span><span class="Identifier">string</span><span class="Other">]</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">auto</span></pre></dt>
<dd>
</dd>
@@ -229,7 +248,7 @@ Alias for <a class="reference external" href="#fail,string">fail[T](string)</a>
<div class="twelve-columns footer">
<span class="nim-sprite"></span>
<br/>
<small style="color: var(--hint);">Made with Nim. Generated: 2020-07-02 16:37:38 UTC</small>
<small style="color: var(--hint);">Made with Nim. Generated: 2020-07-02 17:57:25 UTC</small>
</div>
</div>
</div>

View File

@@ -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)

View File

@@ -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!"
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!"