Enums in Lua

Our enum type ServerState has an underlying int type.

ServerState = {
    StateIdle = 0,
    StateConnected = 1,
    StateError = 2,
    StateRetrying = 3
}

The possible values for ServerState are defined as constants.

By implementing the __tostring method in Lua, values of ServerState can be printed out or converted to strings.

stateName = {
    [ServerState.StateIdle] = "idle",
    [ServerState.StateConnected] = "connected",
    [ServerState.StateError] = "error",
    [ServerState.StateRetrying] = "retrying"
}

function ServerState:__tostring()
    return stateName[self]
end

If we have a value of type int, we cannot pass it to transition - the absence of strict type enforcement in Lua means this provides some degree of runtime checks for enums.

function main()
    local ns = transition(ServerState.StateIdle)
    print(ns)

    local ns2 = transition(ns)
    print(ns2)
end

transition emulates a state transition for a server; it takes the existing state and returns a new state.

function transition(s)
    if s == ServerState.StateIdle then
        return ServerState.StateConnected
    elseif s == ServerState.StateConnected or s == ServerState.StateRetrying then
        return ServerState.StateIdle
    elseif s == ServerState.StateError then
        return ServerState.StateError
    else
        error("unknown state: " .. tostring(s))
    end
end

main()
$ lua enums.lua
connected
idle