about summary refs log tree commit diff stats
path: root/src/utils
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2023-06-18 15:10:25 +0200
committerbptato <nincsnevem662@gmail.com>2023-06-18 15:10:25 +0200
commit8157678366345f9040fe146f354e743d41156867 (patch)
tree99d4bbf68e279414de869b7232384ce86893e2fa /src/utils
parentaecd7e7d69cab7499f07d1ca40541402bbeb286b (diff)
downloadchawan-8157678366345f9040fe146f354e743d41156867.tar.gz
Use utils/opt in toml parser
Diffstat (limited to 'src/utils')
-rw-r--r--src/utils/opt.nim69
-rw-r--r--src/utils/twtstr.nim11
2 files changed, 66 insertions, 14 deletions
diff --git a/src/utils/opt.nim b/src/utils/opt.nim
index 21d79af2..caba236e 100644
--- a/src/utils/opt.nim
+++ b/src/utils/opt.nim
@@ -2,33 +2,84 @@
 
 type
   Result*[T, E] = object
-    val: T
-    has: bool
-    when not (E is void):
-      ex: E
+    when (T is void) and (E is void):
+      has: bool
+    else:
+      case has: bool
+      of true:
+        when not (T is void):
+          val: T
+      else:
+        when not (E is void):
+          ex: E
+        else:
+          discard
 
   Opt*[T] = Result[T, void]
 
+  Err*[E] = Result[void, E]
+
+template ok*[E](t: type Err[E]): Err[E] =
+  Err[E](has: true)
+
 template ok*[T, E](t: type Result[T, E], x: T): Result[T, E] =
   Result[T, E](val: x, has: true)
 
 template ok*[T](x: T): auto =
   ok(typeof(result), x)
 
+template ok*(): auto =
+  ok(typeof(result))
+
 template ok*[T, E](res: var Result[T, E], x: T): Result[T, E] =
-  res.val = x
-  res.has = true
+  res = Result[T, E](has: true, val: x)
 
 template err*[T, E](t: type Result[T, E], e: E): Result[T, E] =
-  Result[T, E](ex: e)
+  Result[T, E](has: false, ex: e)
 
-template err*[E](e: E): auto =
-  err(typeof(result), e)
+template err*[T](t: type Result[T, void]): Result[T, void] =
+  Result[T, void](has: false)
+
+template err*(): auto =
+  err(typeof(result))
 
 template err*[T, E](res: var Result[T, E], e: E) =
   res.ex = e
 
+template err*[E](e: E): auto =
+  err(typeof(result), e)
+
 template isOk*(res: Result): bool = res.has
 template isErr*(res: Result): bool = not res.has
+template isSome*(res: Result): bool = res.isOk
+template isNone*(res: Result): bool = res.isErr
 template get*[T, E](res: Result[T, E]): T = res.val
 template error*[T, E](res: Result[T, E]): E = res.ex
+
+func isSameErr[T, E, F](a: type Result[T, E], b: type F): bool =
+  return E is F
+
+template `?`*[T, E](res: Result[T, E]): T =
+  let x = res # for when res is a funcall
+  if x.has:
+    when not (T is void):
+      x.get
+    else:
+      discard
+  else:
+    when typeof(result) is Result[T, E]:
+      return x
+    elif isSameErr(typeof(result), E):
+      return err(x.error)
+    else:
+      return err()
+
+template `?`*[E](res: Err[E]) =
+  let x = res # for when res is a funcall
+  if not x.has:
+    when typeof(result) is Err[E]:
+      return x
+    elif isSameErr(typeof(result), E):
+      return err(x.error)
+    else:
+      return err()
diff --git a/src/utils/twtstr.nim b/src/utils/twtstr.nim
index dd51eb2d..a988c976 100644
--- a/src/utils/twtstr.nim
+++ b/src/utils/twtstr.nim
@@ -11,6 +11,7 @@ import punycode
 import bindings/libunicode
 import data/idna
 import data/charwidth
+import utils/opt
 
 when defined(posix):
   import posix
@@ -391,7 +392,7 @@ func parseInt32*(s: string): Option[int32] =
     inc i
   return some(sign * integer)
 
-func parseInt64*(s: string): Option[int64] =
+func parseInt64*(s: string): Opt[int64] =
   var sign: int64 = 1
   var i = 0
   if i < s.len and s[i] == '-':
@@ -400,19 +401,19 @@ func parseInt64*(s: string): Option[int64] =
   elif i < s.len and s[i] == '+':
     inc i
   if i == s.len or s[i] notin AsciiDigit:
-    return none(int64)
+    return err()
   var integer = int64(decValue(s[i]))
   inc i
   while i < s.len and isDigit(s[i]):
     if unlikely(integer != 0 and high(int64) div 10 < integer):
-      return none(int64) # overflow
+      return err() # overflow
     integer *= 10
     let c = int64(decValue(s[i]))
     if unlikely(high(int64) - c < integer):
-      return none(int64) # overflow
+      return err() # overflow
     integer += c
     inc i
-  return some(sign * integer)
+  return ok(sign * integer)
 
 func parseUInt8*(s: string): Option[uint8] =
   var i = 0