diff --git a/README.md b/README.md index 6289881..08f66d6 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,125 @@ -# EnumX +# EnumX.jl -`Base.@enum`s protected by a module scope. +This is what I wish [`Base.@enum`][at-enum] was. + +## Usage + +EnumX exports the macro `@enumx`, which works similarly to `Base.@enum`, but with +some improvements. + +The main drawback of `Base.@enum` is that the names for instances +are *not* scoped. This means, for example, that it is inconvenient to use "common" names +for enum instances, and it is impossible to have multiple enums with the same instance +names. + +`EnumX.@enumx` solves these limitations by putting everything behind a module scope such +that instances are hidden and instead accessed using dot-syntax: + +```julia +julia> using EnumX + +julia> @enumx Fruit Apple Banana + +julia> Fruit.Apple +Fruit.Apple = 0 + +julia> Fruit.Banana +Fruit.Banana = 1 +``` + +`Fruit` is a module -- the actual enum type is defined as `Fruit.Type`: + +```julia +julia> Fruit.Type +Enum type Fruit.Type <: Enum{Int32} with 2 instances: + Fruit.Apple = 0 + Fruit.Banana = 1 + +julia> Fruit.Type <: Base.Enum +true +``` + +Since the only reserved name in the example above is the module `Fruit` we can create +another enum with overlapping instance names (this would not be possible with `Base.@enum`): + +```julia +julia> @enumx YellowFruits Banana Lemon + +julia> YellowFruits.Banana +YellowFruits.Banana = 0 +``` + +`@enumx` also allows for duplicate values: + +```julia +julia> Fruit.Type +Enum type Fruit.Type <: Enum{Int32} with 2 instances: + Fruit.Apple = 1 + Fruit.Banana = 1 + +julia> Fruit.Apple +Fruit.Apple = Fruit.Banana = 1 + +julia> Fruit.Banana +Fruit.Apple = Fruit.Banana = 1 +``` + +`@enumx` also lets you use previous enum names for value initialization: +```julia +julia> @enumx Fruit Apple Banana Orange=Apple + +julia> Fruit.Type +Enum type Fruit.Type <: Enum{Int32} with 3 instances: + Fruit.Apple = 0 + Fruit.Banana = 1 + Fruit.Orange = 0 +``` + +Other than that, functionality should be comparable to `Base.@enum`: + + - Base type specification (defaults to `Int32`): + ```julia + julia> @enumx Fruit::UInt8 Apple Banana + + julia> typeof(Integer(Fruit.Apple)) + UInt8 + ``` + + - Specifying values (if not specified, defaults to the value of the previous instance + 1): + ```julia + julia> @enumx Fruit Apple=4 Banana=(1 + 5) Orange + + julia> Fruit.Type + Enum type Fruit.Type <: Enum{Int32} with 3 instances: + Fruit.Apple = 4 + Fruit.Banana = 6 + Fruit.Orange = 7 + ``` + + - Definition with `begin`/`end` block: + ```julia + julia> @enumx Fruit begin + Apple + Banana + Orange + end + ``` + +## See also + +**Community discussions** + - [Encapsulating enum access via dot syntax][discourse-1] + - [Can not reuse enum member in different member][discourse-2] + - [Solving the drawbacks of `@enum`][discourse-3] + +**Related packages** + - [CEnum.jl][CEnum]: C-compatible Enums. + - [SuperEnum.jl][SuperEnum]: Similar approach as EnumX, but doesn't give you `Base.Enum`s. + + +[at-enum]: https://docs.julialang.org/en/v1/base/base/#Base.Enums.@enum +[discourse-1]: https://discourse.julialang.org/t/encapsulating-enum-access-via-dot-syntax/11785 +[discourse-2]: https://discourse.julialang.org/t/cannot-reuse-enum-member-in-different-enum/21342 +[discourse-3]: https://discourse.julialang.org/t/solving-the-drawbacks-of-enum/74506 +[CEnum]: https://github.com/JuliaInterop/CEnum.jl +[SuperEnum]: https://github.com/kindlychung/SuperEnum.jl