Stealing a macro from the `std/setutils` in devel, got an _ok_ implementation
for holey and non-holey enums:
import std/macros
type
X = enum
Z
type
HoleyEnum = enum
AVal = 3
BVal = 5
macro enumElementsAsSet(enm: typed): untyped = result =
newNimNode(nnkCurly).add(enm.getType[1][1..^1])
proc toEnum*(val: SomeInteger, E: typedesc[enum]): E =
const enmRange = E.low.ord .. E.high.ord
when E is Ordinal:
if val in enmRange:
E(val)
else:
raise (ref ValueError)(msg: $val & " cannot be converted to the enum:
" & $E)
else:
if val in enmRange and val.E in E.enumElementsAsSet:
E(val)
else:
raise (ref ValueError)(msg: $val & " cannot be converted to the enum:
" & $E)
var a = 42
let b = a.toEnum(X)
let c = 4.toEnum(HoleyEnum)
Run