Skip to content

Instantly share code, notes, and snippets.

@copygirl
Created October 24, 2018 19:55
Show Gist options
  • Save copygirl/e8c779b6727e85155d1ac223c1433778 to your computer and use it in GitHub Desktop.
Save copygirl/e8c779b6727e85155d1ac223c1433778 to your computer and use it in GitHub Desktop.
import
macros,
options,
sets,
strutils,
typetraits
type
Either2*[T0, T1] = object
case which: range[0..1]
of 0: value0: T0
of 1: value1: T1
proc has*[T0, T1](either: Either2[T0, T1], want: typedesc): bool =
when want is T0: either.which == 0
elif want is T1: either.which == 1
else: {.fatal: ("$# is not a valid type for Either[$#, $#]" % [$want, $type(T0), $type(T1)]).}
proc unsafeGet*[T0, T1](either: Either2[T0, T1], want: typedesc): want =
when want is T0: either.value0
elif want is T1: either.value1
else: {.fatal.}
proc get*[T0, T1](either: Either2[T0, T1], want: typedesc): want =
if not either.has(want): raise newException(ValueError, "either is not a " & $want)
either.unsafeGet(want)
proc set*[T0, T1](either: var Either2[T0, T1], value: T0) =
either.which = 0
either.value0 = value
proc set*[T0, T1](either: var Either2[T0, T1], value: T1) =
either.which = 1
either.value1 = value
proc option*[T0, T1](either: Either2[T0, T1], want: typedesc): Option[want] =
if not either.has(want): return want.none
when want is T0: either.value0.some
elif want is T1: either.value1.some
else: {.fatal.}
proc `[]`*[T0, T1](either: Either2[T0, T1], want: typedesc): want =
either.get(want)
when isMainModule:
var either: Either2[string, int]
either.set("foo")
# echo "type: " & $either.getType()
echo "is string: " & $either.has(string)
echo "is int: " & $either.has(int)
# echo "is bool: " & $either.has(bool)
echo $either[string]
echo $either.option(int)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment