#compdef rustup

typeset -A opt_args

_rustup() {

_arguments \
    '(- 1 *)'{-h,--help}'[show help message]' \
    '(- 1 *)'{-v,--verbose}'[use verbose output]' \
    '(- 1 *)'{-V,--version}'[show version information]' \
    '1: :_rustup_cmds' \
    '*:: :->args'

case $state in
    args)
        case $words[1] in
            component)
                local -a subcommands
                subcommands=(
                'list:list installed and available components'
                'add:add a component to a toolchain'
                'remove:remove a component from a toolchain'
                'help:prints this message or the help of the given subcommand(s)'
                )
                _arguments \
                    '(-h, --help)'{-h,--help}'[show help message]' \
                    '1: :{_describe 'subcommands' subcommands}' \
                    ;;

            default)
                _arguments \
                    '(-h, --help)'{-h,--help}'[show help message]' \
                    ': :_get_local_toolchains'
                    ;;

            doc)
                _arguments \
                    '(-h, --help)'{-h,--help}'[show help message]' \
                    '--book:the Rust Programming Language book' \
                    '--std:standard library API documentation' \
                    ;;

            help)
                _arguments \
                    '(-h, --help)'{-h,--help}'[show help message]' \
                    ': :_rustup_cmds' \
                    ;;

            man)
                _arguments \
                    '(-h, --help)'{-h,--help}'[show help message]' \
                    '--toolchain: :_get_local_toolchains' \
                    ;;

            override)
                local -a subcommands
                subcommands=(
                'list:list directory toolchain overrides'
                'set:set the override toolchain for a directory'
                'unset:remove the override toolchain for a directory'
                'help:prints this message or the help of the given subcommand(s)'
                )
                _arguments \
                    '(-h, --help)'{-h,--help}'[show help message]' \
                    '1: :{_describe 'subcommands' subcommands}' \
                    ;;

            run)
                _arguments \
                    '(-h, --help)'{-h,--help}'[show help message]' \
                    '1: :_get_local_toolchains' \
                    '2:command' \
                    ;;


            self)
                local -a subcommands
                subcommands=(
                'update:download and install updates to rustup'
                'uninstall:uninstall rustup'
                'upgrade-data:upgrade the internal data format'
                'help:prints this message or the help of the given subcommand(s)'
                )
                _arguments \
                    '(-h, --help)'{-h,--help}'[show help message]' \
                    '1: :{_describe 'subcommands' subcommands}' \
                    ;;

            set)
                local -a subcommands
                subcommands=(
                'default-host:The triple used to identify toolchains' \
                'help:prints this message or the help of the given subcommand(s)'
                )
                _arguments \
                    '(-h, --help)'{-h,--help}'[show help message]' \
                    '1: :{_describe 'subcommands' subcommands}' \
                    ;;
            show)
                _arguments \
                    '(-h, --help)'{-h,--help}'[show help message]' \
                    ;;

            target)
                local -a subcommands
                subcommands=(
                'list:list installed and available targets'
                'add:add a target to a toolchain'
                'remove:remove a target from a toolchain'
                'help:prints this message or the help of the given subcommand(s)'
                )
                _arguments \
                    '(-h, --help)'{-h,--help}'[show help message]' \
                    '1: :{_describe 'subcommands' subcommands}' \
                    ;;

            toolchain)
                local -a subcommands
                subcommands=(
                'list:list installed toolchains'
                'install:install or update a toolchain'
                'uninstall:uninstall a toolchain'
                'link:symlink a custom toolchain to a directory'
                'help:prints this message or the help of the given subcommand(s)'
                )
                _arguments \
                    '(-h, --help)'{-h,--help}'[show help message]' \
                    '1: :{_describe 'subcommands' subcommands}' \
                    ;;

            update)
                _arguments \
                    '(-h, --help)'{-h,--help}'[show help message]' \
                    '*: :_get_local_toolchains'
                    ;;

            which)
                _arguments \
                    '(-h, --help)'{-h,--help}'[show help message]' \
                    ':command'
                    ;;
        esac
        ;;
esac
}

_get_local_toolchains() {
    local -a toolchains
    toolchains=()
    rustup toolchain list 2>/dev/null | while read line
    do
        toolchains+="${line%%-*}"
    done
    _describe 'toolchains' toolchains
}

_rustup_cmds(){
local -a commands

commands=(
'show:show the active and installed toolchains'
'update:update Rust toolchains'
'default:set the default toolchain'
'toolchain:modify or query the installed toolchains'
'target:modify a toolchains supported targets'
'component:modify a toolchains installed components'
'override:modify directory toolchain overrides'
'run:run a command with an environment configured for a given toolchain'
'which:display which binary will be run for a given command'
'doc:open the documentation for the current toolchain'
'man:view the man page for a given command'
'self:modify the rustup installation'
'set:alter rustup settings'
'help:prints this message or the help of the given subcommand(s)'
)

_describe 'command' commands

}

_rustup
