2024-08-28 12:36:14 +01:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2024-09-17 18:43:21 +01:00
|
|
|
"bufio"
|
2024-08-28 12:36:14 +01:00
|
|
|
"fmt"
|
2024-09-17 18:43:21 +01:00
|
|
|
"maps"
|
2024-08-28 12:36:14 +01:00
|
|
|
"os"
|
2024-09-17 18:43:21 +01:00
|
|
|
"slices"
|
|
|
|
"time"
|
2024-09-19 11:34:51 +01:00
|
|
|
|
|
|
|
"codeflow.dananglin.me.uk/apollo/pokedex/internal/pokeclient"
|
2024-08-28 12:36:14 +01:00
|
|
|
)
|
|
|
|
|
2024-09-17 18:43:21 +01:00
|
|
|
const (
|
|
|
|
baseURL string = "https://pokeapi.co/api/v2"
|
|
|
|
locationAreaEndpoint string = "/location-area"
|
2024-08-28 12:36:14 +01:00
|
|
|
)
|
|
|
|
|
2024-09-17 18:43:21 +01:00
|
|
|
type State struct {
|
|
|
|
Previous *string
|
|
|
|
Next *string
|
|
|
|
}
|
|
|
|
|
|
|
|
var state State
|
|
|
|
|
|
|
|
type command struct {
|
|
|
|
name string
|
|
|
|
description string
|
2024-09-19 11:34:51 +01:00
|
|
|
callback callbackFunc
|
2024-09-17 18:43:21 +01:00
|
|
|
}
|
|
|
|
|
2024-09-19 11:34:51 +01:00
|
|
|
type callbackFunc func() error
|
|
|
|
|
2024-08-28 12:36:14 +01:00
|
|
|
func main() {
|
2024-09-17 18:43:21 +01:00
|
|
|
run()
|
|
|
|
}
|
|
|
|
|
|
|
|
func run() {
|
2024-09-19 11:34:51 +01:00
|
|
|
client := pokeclient.NewClient(
|
|
|
|
5*time.Minute,
|
|
|
|
10*time.Second,
|
|
|
|
)
|
2024-09-17 18:43:21 +01:00
|
|
|
|
2024-09-19 11:34:51 +01:00
|
|
|
commandMap := map[string]command{
|
2024-09-17 18:43:21 +01:00
|
|
|
"exit": {
|
|
|
|
name: "exit",
|
|
|
|
description: "Exit the Pokedex",
|
|
|
|
callback: commandExit,
|
|
|
|
},
|
|
|
|
"help": {
|
|
|
|
name: "help",
|
|
|
|
description: "Displays a help message",
|
2024-09-19 11:34:51 +01:00
|
|
|
callback: nil,
|
2024-09-17 18:43:21 +01:00
|
|
|
},
|
|
|
|
"map": {
|
|
|
|
name: "map",
|
|
|
|
description: "Displays the next 20 locations in the Pokemon world",
|
2024-09-19 11:34:51 +01:00
|
|
|
callback: commandMap(client),
|
2024-09-17 18:43:21 +01:00
|
|
|
},
|
|
|
|
"mapb": {
|
|
|
|
name: "map back",
|
|
|
|
description: "Displays the previous 20 locations in the Pokemon world",
|
2024-09-19 11:34:51 +01:00
|
|
|
callback: commandMapB(client),
|
2024-09-17 18:43:21 +01:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2024-09-19 11:34:51 +01:00
|
|
|
summaries := summaryMap(commandMap)
|
2024-09-17 18:43:21 +01:00
|
|
|
|
2024-09-19 11:34:51 +01:00
|
|
|
commandMap["help"] = command{
|
|
|
|
name: "help",
|
|
|
|
description: "Displays a help message",
|
|
|
|
callback: commandHelp(summaries),
|
2024-09-17 18:43:21 +01:00
|
|
|
}
|
|
|
|
|
2024-09-19 11:34:51 +01:00
|
|
|
fmt.Printf("\nWelcome to the Pokedex!\n")
|
|
|
|
fmt.Print("\npokedex > ")
|
|
|
|
|
|
|
|
scanner := bufio.NewScanner(os.Stdin)
|
|
|
|
|
|
|
|
for scanner.Scan() {
|
|
|
|
command := scanner.Text()
|
|
|
|
|
|
|
|
cmd, ok := commandMap[command]
|
|
|
|
if !ok {
|
|
|
|
fmt.Println("ERROR: Unrecognised command.")
|
|
|
|
|
|
|
|
fmt.Print("\npokedex > ")
|
|
|
|
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
if cmd.callback == nil {
|
|
|
|
fmt.Println("ERROR: This command is defined but does not have a callback function.")
|
|
|
|
|
|
|
|
fmt.Print("\npokedex > ")
|
2024-09-17 18:43:21 +01:00
|
|
|
|
2024-09-19 11:34:51 +01:00
|
|
|
continue
|
|
|
|
}
|
2024-09-17 18:43:21 +01:00
|
|
|
|
2024-09-19 11:34:51 +01:00
|
|
|
if err := commandMap[command].callback(); err != nil {
|
|
|
|
fmt.Printf("ERROR: %v.\n", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Print("pokedex > ")
|
2024-09-17 18:43:21 +01:00
|
|
|
}
|
2024-09-19 11:34:51 +01:00
|
|
|
}
|
2024-09-17 18:43:21 +01:00
|
|
|
|
2024-09-19 11:34:51 +01:00
|
|
|
func commandHelp(summaries map[string]string) callbackFunc {
|
|
|
|
return func() error {
|
|
|
|
keys := []string{}
|
2024-09-17 18:43:21 +01:00
|
|
|
|
2024-09-19 11:34:51 +01:00
|
|
|
for key := range maps.All(summaries) {
|
|
|
|
keys = append(keys, key)
|
|
|
|
}
|
|
|
|
|
|
|
|
slices.Sort(keys)
|
|
|
|
|
|
|
|
fmt.Printf("\nCommands:\n")
|
|
|
|
|
|
|
|
for _, key := range slices.All(keys) {
|
|
|
|
fmt.Printf("\n%s: %s", key, summaries[key])
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Printf("\n\n")
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
2024-09-17 18:43:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func commandExit() error {
|
|
|
|
os.Exit(0)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-09-19 11:34:51 +01:00
|
|
|
func commandMap(client *pokeclient.Client) callbackFunc {
|
|
|
|
return func() error {
|
|
|
|
url := state.Next
|
|
|
|
if url == nil {
|
|
|
|
url = new(string)
|
|
|
|
*url = baseURL + locationAreaEndpoint
|
|
|
|
}
|
2024-09-17 18:43:21 +01:00
|
|
|
|
2024-09-19 11:34:51 +01:00
|
|
|
return printResourceList(client, *url)
|
2024-09-17 18:43:21 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-09-19 11:34:51 +01:00
|
|
|
func commandMapB(client *pokeclient.Client) callbackFunc {
|
|
|
|
return func() error {
|
|
|
|
url := state.Previous
|
|
|
|
if url == nil {
|
|
|
|
return fmt.Errorf("no previous locations available")
|
|
|
|
}
|
2024-09-17 18:43:21 +01:00
|
|
|
|
2024-09-19 11:34:51 +01:00
|
|
|
return printResourceList(client, *url)
|
2024-09-17 18:43:21 +01:00
|
|
|
}
|
2024-09-19 11:34:51 +01:00
|
|
|
}
|
2024-09-17 18:43:21 +01:00
|
|
|
|
2024-09-19 11:34:51 +01:00
|
|
|
func printResourceList(client *pokeclient.Client, url string) error {
|
|
|
|
list, err := client.GetNamedAPIResourceList(url)
|
2024-09-17 18:43:21 +01:00
|
|
|
if err != nil {
|
2024-09-19 11:34:51 +01:00
|
|
|
return fmt.Errorf("unable to get the list of resources: %w", err)
|
2024-09-17 18:43:21 +01:00
|
|
|
}
|
|
|
|
|
2024-09-19 11:34:51 +01:00
|
|
|
state.Next = list.Next
|
|
|
|
state.Previous = list.Previous
|
2024-09-17 18:43:21 +01:00
|
|
|
|
2024-09-19 11:34:51 +01:00
|
|
|
for _, location := range slices.All(list.Results) {
|
|
|
|
fmt.Println(location.Name)
|
2024-09-17 18:43:21 +01:00
|
|
|
}
|
|
|
|
|
2024-09-19 11:34:51 +01:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func summaryMap(commandMap map[string]command) map[string]string {
|
|
|
|
summaries := make(map[string]string)
|
2024-09-17 18:43:21 +01:00
|
|
|
|
2024-09-19 11:34:51 +01:00
|
|
|
for key, value := range maps.All(commandMap) {
|
|
|
|
summaries[key] = value.description
|
2024-09-17 18:43:21 +01:00
|
|
|
}
|
|
|
|
|
2024-09-19 11:34:51 +01:00
|
|
|
return summaries
|
2024-08-28 12:36:14 +01:00
|
|
|
}
|