From 0148583f5bb8e4c0019872cbea38f421f60f7f26 Mon Sep 17 00:00:00 2001 From: Darius Rapalis Date: Mon, 10 Mar 2025 22:14:46 +0200 Subject: [PATCH] #5 --- main.go | 71 ++++++++++++++++++++++++++++++++++---- pokeapi/client.go | 20 +++++++++++ pokeapi/location_list.go | 42 ++++++++++++++++++++++ pokeapi/pokeapi.go | 5 +++ pokeapi/types_locations.go | 12 +++++++ 5 files changed, 144 insertions(+), 6 deletions(-) create mode 100644 pokeapi/client.go create mode 100644 pokeapi/location_list.go create mode 100644 pokeapi/pokeapi.go create mode 100644 pokeapi/types_locations.go diff --git a/main.go b/main.go index f46e80f..34d9ba5 100644 --- a/main.go +++ b/main.go @@ -2,20 +2,35 @@ package main import ( "bufio" + "errors" "fmt" + "github.com/rdarius/boot-dev-pokedex/pokeapi" "os" "strings" + "time" ) +type config struct { + pokeapiClient pokeapi.Client + nextLocationsURL *string + prevLocationsURL *string +} + type cliCommand struct { name string description string - callback func() error + callback func(*config) error } var commands map[string]cliCommand func main() { + + pokeClient := pokeapi.NewClient(5 * time.Second) + cfg := &config{ + pokeapiClient: pokeClient, + } + commands = map[string]cliCommand{ "exit": { name: "exit", @@ -27,6 +42,16 @@ func main() { description: "Display a help message", callback: printHelpMessage, }, + "map": { + name: "map", + description: "Get the next page of locations", + callback: commandMapf, + }, + "mapb": { + name: "mapb", + description: "Get the previous page of locations", + callback: commandMapb, + }, } for { // read user input @@ -40,7 +65,7 @@ func main() { //check if command is in commands map cmd, ok := commands[command] if ok { - err := cmd.callback() + err := cmd.callback(cfg) if err != nil { fmt.Println(err) } @@ -52,7 +77,7 @@ func main() { } } -func commandExit() error { +func commandExit(*config) error { fmt.Println("Closing the Pokedex... Goodbye!") os.Exit(0) return nil @@ -70,10 +95,44 @@ func cleanInput(text string) []string { return separated } -func printHelpMessage() error { +func printHelpMessage(*config) error { fmt.Print("Welcome to the Pokedex!\nUsage:\n\n") - for k, v := range commands { - fmt.Printf("%s: %s\n", k, v.description) + for _, v := range commands { + fmt.Printf("%s: %s\n", v.name, v.description) + } + return nil +} + +func commandMapf(cfg *config) error { + locationsResp, err := cfg.pokeapiClient.ListLocations(cfg.nextLocationsURL) + if err != nil { + return err + } + + cfg.nextLocationsURL = locationsResp.Next + cfg.prevLocationsURL = locationsResp.Previous + + for _, loc := range locationsResp.Results { + fmt.Println(loc.Name) + } + return nil +} + +func commandMapb(cfg *config) error { + if cfg.prevLocationsURL == nil { + return errors.New("you're on the first page") + } + + locationResp, err := cfg.pokeapiClient.ListLocations(cfg.prevLocationsURL) + if err != nil { + return err + } + + cfg.nextLocationsURL = locationResp.Next + cfg.prevLocationsURL = locationResp.Previous + + for _, loc := range locationResp.Results { + fmt.Println(loc.Name) } return nil } diff --git a/pokeapi/client.go b/pokeapi/client.go new file mode 100644 index 0000000..61e89dc --- /dev/null +++ b/pokeapi/client.go @@ -0,0 +1,20 @@ +package pokeapi + +import ( + "net/http" + "time" +) + +// Client - +type Client struct { + httpClient http.Client +} + +// NewClient - +func NewClient(timeout time.Duration) Client { + return Client{ + httpClient: http.Client{ + Timeout: timeout, + }, + } +} diff --git a/pokeapi/location_list.go b/pokeapi/location_list.go new file mode 100644 index 0000000..df2fefe --- /dev/null +++ b/pokeapi/location_list.go @@ -0,0 +1,42 @@ +package pokeapi + +import ( + "encoding/json" + "io" + "net/http" +) + +// ListLocations - +func (c *Client) ListLocations(pageURL *string) (RespShallowLocations, error) { + url := baseURL + "/location-area" + if pageURL != nil { + url = *pageURL + } + + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return RespShallowLocations{}, err + } + + resp, err := c.httpClient.Do(req) + if err != nil { + return RespShallowLocations{}, err + } + + defer func(Body io.ReadCloser) { + _ = Body.Close() + }(resp.Body) + + dat, err := io.ReadAll(resp.Body) + if err != nil { + return RespShallowLocations{}, err + } + + locationsResp := RespShallowLocations{} + err = json.Unmarshal(dat, &locationsResp) + if err != nil { + return RespShallowLocations{}, err + } + + return locationsResp, nil +} diff --git a/pokeapi/pokeapi.go b/pokeapi/pokeapi.go new file mode 100644 index 0000000..6b98b76 --- /dev/null +++ b/pokeapi/pokeapi.go @@ -0,0 +1,5 @@ +package pokeapi + +const ( + baseURL = "https://pokeapi.co/api/v2" +) diff --git a/pokeapi/types_locations.go b/pokeapi/types_locations.go new file mode 100644 index 0000000..7250410 --- /dev/null +++ b/pokeapi/types_locations.go @@ -0,0 +1,12 @@ +package pokeapi + +// RespShallowLocations - +type RespShallowLocations struct { + Count int `json:"count"` + Next *string `json:"next"` + Previous *string `json:"previous"` + Results []struct { + Name string `json:"name"` + URL string `json:"url"` + } `json:"results"` +}