diff --git a/main.go b/main.go index 48d6ea9..8966c06 100644 --- a/main.go +++ b/main.go @@ -19,7 +19,7 @@ type config struct { type cliCommand struct { name string description string - callback func(*config) error + callback func(*config, ...string) error } var commands map[string]cliCommand @@ -37,6 +37,11 @@ func main() { description: "Exit the Pokedex", callback: commandExit, }, + "explore": { + name: "explore ", + description: "Explore a location", + callback: commandExplore, + }, "help": { name: "help", description: "Display a help message", @@ -61,11 +66,14 @@ func main() { word := input.Text() cleanedWord := cleanInput(word) command := cleanedWord[0] - + var args []string + if len(cleanedWord) > 1 { + args = cleanedWord[1:] + } //check if command is in commands map cmd, ok := commands[command] if ok { - err := cmd.callback(cfg) + err := cmd.callback(cfg, args...) if err != nil { fmt.Println(err) } @@ -77,7 +85,7 @@ func main() { } } -func commandExit(*config) error { +func commandExit(*config, ...string) error { fmt.Println("Closing the Pokedex... Goodbye!") os.Exit(0) return nil @@ -89,7 +97,7 @@ func cleanInput(text string) []string { return words } -func printHelpMessage(*config) error { +func printHelpMessage(*config, ...string) error { fmt.Print("Welcome to the Pokedex!\nUsage:\n\n") for _, v := range commands { fmt.Printf("%s: %s\n", v.name, v.description) @@ -97,7 +105,7 @@ func printHelpMessage(*config) error { return nil } -func commandMapf(cfg *config) error { +func commandMapf(cfg *config, _ ...string) error { locationsResp, err := cfg.pokeapiClient.ListLocations(cfg.nextLocationsURL) if err != nil { return err @@ -112,7 +120,7 @@ func commandMapf(cfg *config) error { return nil } -func commandMapb(cfg *config) error { +func commandMapb(cfg *config, _ ...string) error { if cfg.prevLocationsURL == nil { return errors.New("you're on the first page") } @@ -130,3 +138,21 @@ func commandMapb(cfg *config) error { } return nil } + +func commandExplore(cfg *config, args ...string) error { + if len(args) != 1 { + return errors.New("you must provide a location name") + } + + name := args[0] + location, err := cfg.pokeapiClient.GetLocation(name) + if err != nil { + return err + } + fmt.Printf("Exploring %s...\n", location.Name) + fmt.Println("Found Pokemon: ") + for _, enc := range location.PokemonEncounters { + fmt.Printf(" - %s\n", enc.Pokemon.Name) + } + return nil +} diff --git a/pokeapi/location_get.go b/pokeapi/location_get.go new file mode 100644 index 0000000..c380882 --- /dev/null +++ b/pokeapi/location_get.go @@ -0,0 +1,49 @@ +package pokeapi + +import ( + "encoding/json" + "io" + "net/http" +) + +// GetLocation - +func (c *Client) GetLocation(locationName string) (Location, error) { + url := baseURL + "/location-area/" + locationName + + if val, ok := c.cache.Get(url); ok { + locationResp := Location{} + err := json.Unmarshal(val, &locationResp) + if err != nil { + return Location{}, err + } + return locationResp, nil + } + + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return Location{}, err + } + + resp, err := c.httpClient.Do(req) + if err != nil { + return Location{}, err + } + defer func(Body io.ReadCloser) { + _ = Body.Close() + }(resp.Body) + + dat, err := io.ReadAll(resp.Body) + if err != nil { + return Location{}, err + } + + locationResp := Location{} + err = json.Unmarshal(dat, &locationResp) + if err != nil { + return Location{}, err + } + + c.cache.Add(url, dat) + + return locationResp, nil +} diff --git a/pokeapi/types_locations.go b/pokeapi/types_locations.go index 7250410..2aa82c4 100644 --- a/pokeapi/types_locations.go +++ b/pokeapi/types_locations.go @@ -10,3 +10,57 @@ type RespShallowLocations struct { URL string `json:"url"` } `json:"results"` } + +// Location - +type Location struct { + EncounterMethodRates []struct { + EncounterMethod struct { + Name string `json:"name"` + URL string `json:"url"` + } `json:"encounter_method"` + VersionDetails []struct { + Rate int `json:"rate"` + Version struct { + Name string `json:"name"` + URL string `json:"url"` + } `json:"version"` + } `json:"version_details"` + } `json:"encounter_method_rates"` + GameIndex int `json:"game_index"` + ID int `json:"id"` + Location struct { + Name string `json:"name"` + URL string `json:"url"` + } `json:"location"` + Name string `json:"name"` + Names []struct { + Language struct { + Name string `json:"name"` + URL string `json:"url"` + } `json:"language"` + Name string `json:"name"` + } `json:"names"` + PokemonEncounters []struct { + Pokemon struct { + Name string `json:"name"` + URL string `json:"url"` + } `json:"pokemon"` + VersionDetails []struct { + EncounterDetails []struct { + Chance int `json:"chance"` + ConditionValues []interface{} `json:"condition_values"` + MaxLevel int `json:"max_level"` + Method struct { + Name string `json:"name"` + URL string `json:"url"` + } `json:"method"` + MinLevel int `json:"min_level"` + } `json:"encounter_details"` + MaxChance int `json:"max_chance"` + Version struct { + Name string `json:"name"` + URL string `json:"url"` + } `json:"version"` + } `json:"version_details"` + } `json:"pokemon_encounters"` +}