Skip to content

Instantly share code, notes, and snippets.

@quinnj
Created March 28, 2020 16:56
Show Gist options
  • Save quinnj/8ad3234673056d1df28562a7a2aa9e02 to your computer and use it in GitHub Desktop.
Save quinnj/8ad3234673056d1df28562a7a2aa9e02 to your computer and use it in GitHub Desktop.
module ScopedEnums
using StructTypes
export @scopedenum
macro scopedenum(T, args...)
blk = esc(:(
module $(Symbol("$(T)Module"))
using StructTypes
export $T
struct $T
value::Int64
end
const NAME2VALUE = $(Dict(String(x.args[1])=>Int64(x.args[2]) for x in args))
$T(str::String) = $T(NAME2VALUE[str])
const VALUE2NAME = $(Dict(Int64(x.args[2])=>String(x.args[1]) for x in args))
Base.string(e::$T) = VALUE2NAME[e.value]
Base.getproperty(::Type{$T}, sym::Symbol) = haskey(NAME2VALUE, String(sym)) ? $T(String(sym)) : getfield($T, sym)
Base.show(io::IO, e::$T) = print(io, string($T, ".", string(e), " = ", e.value))
StructTypes.StructType(::Type{$T}) = StructTypes.StringType()
end
))
top = Expr(:toplevel, blk)
push!(top.args, :(using .$(Symbol("$(T)Module"))))
return top
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment