package main import ( "bufio" "fmt" "os" "strings" "time" "k3gtpi.jumpingcrab.com/go-learning/pokedexcli/internal/pokecache" ) type cliCommand struct { name string description string callback func(*PokedexConfig, *string) error } type PokedexLocationData struct { Next *string `json:"next"` Previous *string `json:"previous"` Locations []map[string]string `json:"results"` } type PokemonSummary struct { Name string `json:"name"` DataUrl string `json:"url"` } type PokemonStat struct { Name string `json:"name"` } type PokemonStats struct { BaseStat int `json:"base_stat"` PokeStat PokemonStat `json:"stat"` } type PokemonTypeEntry struct { Name string `json:"name"` } type PokemonTypes struct { PokeType PokemonTypeEntry `json:"type"` } type PokemonDetails struct { Name string `json:"name"` BaseExperience int `json:"base_experience"` Weight int `json:"weight"` Height int `json:"height"` PokeStats []PokemonStats `json:"stats"` PokeTypes []PokemonTypes `json:"types"` } type PokemonEncounterData struct { PokemonSummary PokemonSummary `json:"pokemon"` } type PokedexLocalPokemons struct { LocationName string `json:"name"` PokemonEncounters []PokemonEncounterData `json:"pokemon_encounters"` } type PokedexConfig struct { Cache *pokecache.Cache LocationData PokedexLocationData LocalPokemons PokedexLocalPokemons CaughtPokemon []PokemonDetails } func startRepl() { reader := bufio.NewScanner(os.Stdin) fmt.Println("Welcome to the Pokedex!") pokedexConfig := PokedexConfig{} pokedexConfig.Cache = pokecache.NewCache(5 * time.Second) for { fmt.Printf("Pokedex > ") reader.Scan() words := cleanInput(reader.Text()) if len(words) == 0 { continue } else if len(words) > 2 { fmt.Printf("Commands can only take one argument!") continue } commandName := words[0] command, valid := getCommands()[commandName] if !valid { fmt.Println("Unknown command.") continue } arg := "" if len(words) == 2 { arg = words[1] } if err := command.callback(&pokedexConfig, &arg); err != nil { fmt.Printf("Encountered error running command: %v\nErr: %v\n\n", command.name, err) } } } func cleanInput(text string) []string { if len(text) == 0 { fmt.Println("Input is empty!") return []string{} } output := strings.ToLower(text) words := strings.Fields(output) return words } func getCommands() map[string]cliCommand { return map[string]cliCommand{ "help": { name: "help", description: "Prints this help menu.", callback: commandHelp, }, "exit": { name: "exit", description: "Exits the Pokedex", callback: commandExit, }, "map": { name: "map", description: "Print Pokemon world locations.", callback: commandMap, }, "mapb": { name: "mapb", description: "Print previous Pokemon locations.", callback: commandMapb, }, "explore": { name: "explore", description: "Print Pokemon found in specified area. Requires AREA_NAME argument.", callback: commandExplore, }, "catch": { name: "catch", description: "Attempt to catch a Pokemon present in current area. Requires POKEMON_NAME argument.", callback: commandCatch, }, "inspect": { name: "inspect", description: "Inspect a caught Pokemon. Requires POKEMON_NAME argument.", callback: commandInspect, }, "pokedex": { name: "pokedex", description: "Inspect the Pokedex contents.", callback: commandPokedex, }, } }