pokedex_cli/repl.go

162 lines
3.6 KiB
Go
Raw Permalink Normal View History

2025-09-28 20:15:55 +00:00
package main
import (
"bufio"
"fmt"
2025-09-28 20:15:55 +00:00
"os"
"strings"
2025-10-04 17:29:20 +00:00
"time"
"k3gtpi.jumpingcrab.com/go-learning/pokedexcli/internal/pokecache"
2025-09-28 20:15:55 +00:00
)
type cliCommand struct {
name string
description string
callback func(*PokedexConfig, *string) error
2025-10-04 17:29:20 +00:00
}
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"`
2025-09-28 20:15:55 +00:00
}
type PokedexLocalPokemons struct {
LocationName string `json:"name"`
PokemonEncounters []PokemonEncounterData `json:"pokemon_encounters"`
}
type PokedexConfig struct {
Cache *pokecache.Cache
LocationData PokedexLocationData
LocalPokemons PokedexLocalPokemons
CaughtPokemon []PokemonDetails
}
2025-09-28 20:15:55 +00:00
func startRepl() {
reader := bufio.NewScanner(os.Stdin)
fmt.Println("Welcome to the Pokedex!")
2025-10-04 17:29:20 +00:00
pokedexConfig := PokedexConfig{}
pokedexConfig.Cache = pokecache.NewCache(5 * time.Second)
2025-09-28 20:15:55 +00:00
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
2025-09-28 20:15:55 +00:00
}
commandName := words[0]
2025-09-28 20:15:55 +00:00
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)
2025-09-28 20:15:55 +00:00
}
}
}
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 {
2025-09-28 20:15:55 +00:00
return map[string]cliCommand{
"help": {
name: "help",
description: "Prints this help menu.",
callback: commandHelp,
2025-09-28 20:15:55 +00:00
},
"exit": {
name: "exit",
description: "Exits the Pokedex",
callback: commandExit,
2025-09-28 20:15:55 +00:00
},
2025-09-28 20:57:48 +00:00
"map": {
name: "map",
description: "Print Pokemon world locations.",
callback: commandMap,
2025-09-28 20:57:48 +00:00
},
2025-10-04 17:29:20 +00:00
"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,
2025-10-04 17:29:20 +00:00
},
2025-09-28 20:15:55 +00:00
}
}