You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

152 lines
3.3 KiB
Go

package main
import (
"bufio"
"errors"
"fmt"
"os"
"strings"
)
type Animal interface {
Eat()
Move()
Speak()
}
type Cow struct {
name string
food string `default:"grass"`
locomotion string `default:"walk"`
sound string `default:"moo"`
}
func (a Cow) Eat() {
fmt.Println(a.food)
}
func (a Cow) Move() {
fmt.Println(a.locomotion)
}
func (a Cow) Speak() {
fmt.Println(a.sound)
}
type Bird struct {
Name string
Food string `default:"worms"`
Locomotion string `default:"fly"`
Sound string `default:"peep"`
}
func (a Bird) Eat() {
fmt.Println(a.Food)
}
func (a Bird) Move() {
fmt.Println(a.Locomotion)
}
func (a Bird) Speak() {
fmt.Println(a.Sound)
}
type Snake struct {
Name string
Food string `default:"mice"`
Locomotion string `default:"slither"`
Sound string `default:"hsss"`
}
func (a Snake) Eat() {
fmt.Println(a.Food)
}
func (a Snake) Move() {
fmt.Println(a.Locomotion)
}
func (a Snake) Speak() {
fmt.Println(a.Sound)
}
func NewAnimal(name string, animalType string) (Animal, error) {
switch animalType {
case "cow":
return Cow{name, "grass", "walk", "moo"}, nil
case "bird":
return Bird{name, "worms", "fly", "peep"}, nil
case "snake":
return Snake{name, "mice", "slither", "hiss"}, nil
default:
return Cow{}, errors.New(fmt.Sprintf("Error! Failed to create animal of type: %s. Options {cow, bird, snake}.", animalType))
}
}
func queryAnimal(animal Animal, query string) {
switch query {
case "eat":
animal.Eat()
case "move":
animal.Move()
case "speak":
animal.Speak()
default:
fmt.Printf("Error! Query parameter: %s invalid. Options: {eat, move, speak}\n", query)
}
}
// Use the empty interface to map string to Any type
// var animalMap map[string]interface{}
var animalMap map[string]Animal
func main() {
animalMap = make(map[string]Animal)
scanner := bufio.NewScanner(os.Stdin)
fmt.Println("\n\nWelcome to your personal animal database. Two commands are available {newanimal, query}\n")
fmt.Println("The \"newanimal\" command takes two parameters (name, animalType) seperated by white space.")
fmt.Println("\"newanimal\" animal types are restricted to {cow, bird, snake}")
fmt.Println("Example: \"newanimal bob cow\"\n")
fmt.Println("The \"query\" command takes two parameters (name, action) seperated by white space.")
fmt.Println("\"query\" actions are restricted to {eat, move, speak}")
fmt.Println("Example: \"query bob eat\"\n")
for {
fmt.Print(">")
scanner.Scan()
input := scanner.Text()
input = strings.TrimSpace(input)
splitInput := strings.Fields(input)
// Ensure user command is proper size
if len(splitInput) != 3 {
fmt.Println("Error! Invalid input parameters. Please try again.")
continue
}
command := splitInput[0]
animalName := splitInput[1]
arg := splitInput[2]
switch command {
case "newanimal":
userAnimal, err := NewAnimal(animalName, arg)
if err != nil {
fmt.Println(err)
continue
}
animalMap[animalName] = userAnimal
case "query":
// check animal is in datastore
val, present := animalMap[animalName]
if present {
queryAnimal(val, arg)
} else {
fmt.Printf("Error! Failed to find animal %s in database\n", animalName)
}
default:
fmt.Println("Error! Unrecognized user command. Options {newanimal, query}")
}
}
}