Enums in Co-array Fortran

Our enum type ServerState has an underlying integer type.

module server_states
  implicit none
  integer, parameter :: StateIdle = 0
  integer, parameter :: StateConnected = 1
  integer, parameter :: StateError = 2
  integer, parameter :: StateRetrying = 3
contains

  function state_name(state) result(name)
    integer, intent(in) :: state
    character(len=20) :: name
    select case (state)
    case (StateIdle)
      name = 'idle'
    case (StateConnected)
      name = 'connected'
    case (StateError)
      name = 'error'
    case (StateRetrying)
      name = 'retrying'
    case default
      name = 'unknown'
    end select
  end function state_name

  function transition(s) result(ns)
    integer, intent(in) :: s
    integer :: ns
    select case (s)
    case (StateIdle)
      ns = StateConnected
    case (StateConnected, StateRetrying)
      ns = StateIdle
    case (StateError)
      ns = StateError
    case default
      print *, 'Error: unknown state'
      stop 1
    end select
  end function transition

end module server_states

program main
  use server_states
  implicit none
  integer :: ns, ns2
  
  ns = transition(StateIdle)
  print *, state_name(ns)
  
  ns2 = transition(ns)
  print *, state_name(ns2)
  
end program main

To compile and run this program, you can use a Fortran compiler like gfortran.

$ gfortran -o server server_states.f90
$ ./server
 connected
 idle

In this example, we define the possible states of the server using parameters (constants). We have a state_name function to convert the states to strings and a transition function to handle state transitions. The main program demonstrates these by transitioning from StateIdle to StateConnected, then back to StateIdle.