diff --git a/command_exit.go b/command_exit.go index ca866ff..f2df532 100644 --- a/command_exit.go +++ b/command_exit.go @@ -5,7 +5,7 @@ import ( "os" ) -func commandExit() error { +func commandExit(cfg *config) error { fmt.Println("Closing the Pokedex... Goodbye!") os.Exit(0) return nil diff --git a/command_help.go b/command_help.go index 81807fe..ed990e0 100644 --- a/command_help.go +++ b/command_help.go @@ -2,7 +2,7 @@ package main import "fmt" -func commandHelp() error { +func commandHelp(cfg *config) error { fmt.Println() fmt.Println("Welcome to the Pokedex!") fmt.Println("Usage:") diff --git a/command_map.go b/command_map.go new file mode 100644 index 0000000..e4a4db8 --- /dev/null +++ b/command_map.go @@ -0,0 +1,46 @@ +package main + +import ( + "errors" + "fmt" +) + +func commandMap(cfg *config) error { + if cfg.nextLocationsURL == nil { + return errors.New("you're on the last page") + } + + locationsResp, err := cfg.pokeClient.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") + } + + locationsResp, err := cfg.pokeClient.ListLocations(cfg.prevLocationsURL) + if err != nil { + return err + } + + cfg.nextLocationsURL = locationsResp.Next + cfg.prevLocationsURL = locationsResp.Previous + + for _, loc := range locationsResp.Results { + fmt.Println(" ", loc.Name) + } + + return nil +} diff --git a/internal/pokeapi/client.go b/internal/pokeapi/client.go new file mode 100644 index 0000000..a2c36d9 --- /dev/null +++ b/internal/pokeapi/client.go @@ -0,0 +1,18 @@ +package pokeapi + +import ( + "net/http" + "time" +) + +type Client struct { + httpClient http.Client +} + +func NewClient(timeout time.Duration) Client { + return Client{ + httpClient: http.Client{ + Timeout: timeout, + }, + } +} diff --git a/internal/pokeapi/location_list.go b/internal/pokeapi/location_list.go new file mode 100644 index 0000000..c6dd218 --- /dev/null +++ b/internal/pokeapi/location_list.go @@ -0,0 +1,32 @@ +package pokeapi + +import ( + "encoding/json" + "net/http" +) + +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 resp.Body.Close() + + var locationsResp RespShallowLocations + decoder := json.NewDecoder(resp.Body) + if err = decoder.Decode(&locationsResp); err != nil { + return RespShallowLocations{}, err + } + + return locationsResp, nil +} diff --git a/internal/pokeapi/pokeapi.go b/internal/pokeapi/pokeapi.go new file mode 100644 index 0000000..bf0b848 --- /dev/null +++ b/internal/pokeapi/pokeapi.go @@ -0,0 +1,5 @@ +package pokeapi + +const ( + baseUrl = "https://pokeapi.co/api/v2" +) diff --git a/internal/pokeapi/types_locations.go b/internal/pokeapi/types_locations.go new file mode 100644 index 0000000..3f01b52 --- /dev/null +++ b/internal/pokeapi/types_locations.go @@ -0,0 +1,11 @@ +package pokeapi + +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"` +} diff --git a/main.go b/main.go index cc05093..d5f3bce 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,17 @@ package main +import ( + "time" + + "git.eo13-dev.com/enordaz/gokedex/internal/pokeapi" +) + const prompt = "Pokedex > " func main() { - startRepl() + pokeClient := pokeapi.NewClient(5 * time.Second) + cfg := &config{ + pokeClient: pokeClient, + } + startRepl(cfg) } diff --git a/repl.go b/repl.go index 3c46349..4d7f809 100644 --- a/repl.go +++ b/repl.go @@ -5,6 +5,8 @@ import ( "fmt" "os" "strings" + + "git.eo13-dev.com/enordaz/gokedex/internal/pokeapi" ) func getCommands() map[string]cliCommand { @@ -22,15 +24,17 @@ func getCommands() map[string]cliCommand { "map": { name: "map", description: "Displays the names of the next 20 locations", + callback: commandMap, }, "mapb": { name: "mapb", description: "Displays the names of the previous 20 locations", + callback: commandMapb, }, } } -func startRepl() { +func startRepl(cfg *config) { reader := bufio.NewScanner(os.Stdin) for { fmt.Print(prompt) @@ -45,13 +49,13 @@ func startRepl() { command, exists := getCommands()[inputCommand] if exists { - err := command.callback() + err := command.callback(cfg) if err != nil { - fmt.Printf("%v error: %v", command.name, err.Error()) + fmt.Printf("%v error: %v\n", command.name, err.Error()) } } else { - fmt.Println("Unknown command") + fmt.Println("unknown command") continue } @@ -61,7 +65,13 @@ func startRepl() { type cliCommand struct { name string description string - callback func() error + callback func(*config) error +} + +type config struct { + pokeClient pokeapi.Client + nextLocationsURL *string + prevLocationsURL *string } func cleanInput(text string) []string {