Writing CLI tool - How to structure the main method

I am currently working on my hobby CLI project.

Is there an idiomatic way to structure the main method? I’m currently doing validation → route to a command → handle_exit. Validation itself returns an error, never halts process by itself.

This is the rough design I did:

def main(args) do
  ensure_config_dir!()

  args
  |> parse_args() # calls OptionsParser.parse/Validates for all commands
  |> case do # Route to a command
    :list -> CLI.List.run()
    {:create resource, opts} -> CLI.Create.run(resource, opts)
    {:delete, resorce} -> CLI.Delete.run(resource)
    error -> error
  end
  |> handle_command_result() # Calls one of these: IO.puts(result), System.halt(1), print_usage()
end

Everything after the parse is very simple and reads nice, but I feel like I crammed all the complexity into the parsing.