github.com/packtpublishing/learning-functional-programming-in-go@v0.0.0-20230130084745-8b849f6d58c4/Chapter07/func-param/src/utils/options.go (about) 1 package utils 2 3 import ( 4 "flag" 5 "fmt" 6 "github.com/BurntSushi/toml" 7 "reflect" 8 "strconv" 9 "github.com/pkg/errors" 10 ) 11 12 type Conf struct { 13 Port string `toml:"port"` 14 LogDebugInfo bool `toml:"log_debug_info"` 15 MaxConcurrentConnections int `toml:"max_concurrent_connections"` 16 MaxNumber int `toml:"max_number"` 17 UseNumberHandler bool `toml:"use_number_handler"` 18 } 19 20 var Config Conf 21 22 func GetOptions() bool { 23 var configFile string 24 25 flag.StringVar(&configFile, "config", "", "Configuration file") 26 flag.StringVar(&Config.Port, "port", "8080", "Port that the API listens on") 27 flag.BoolVar(&Config.LogDebugInfo, "log-debug-info", false, "Whether to log debug output to the log (set to true for debug purposes)") 28 flag.IntVar(&Config.MaxConcurrentConnections, "max-concurrent-connections", 6, "Maximum number of concurrent connections (not currently used)") 29 flag.IntVar(&Config.MaxNumber, "max_number", 10, "Maximum number that user is allowed to enter") 30 flag.BoolVar(&Config.UseNumberHandler, "use-number-handler", true, "Use number handler (to display number, optionally with FormatNumber applied) else display files in project root") 31 32 flag.Parse() 33 34 if configFile != "" { 35 if _, err := toml.DecodeFile(configFile, &Config); err != nil { 36 HandlePanic(errors.Wrap(err, "unable to read config file")) 37 } 38 } 39 return true 40 } 41 42 type Datastore interface {} 43 44 // UpdateConfigVal returns string representation of old config value 45 func UpdateConfigVal(d Datastore, key, val string) (oldValue string) { 46 Debug.Printf("key (%s), val (%v)\n", key, val) 47 value := reflect.ValueOf(d) 48 if value.Kind() != reflect.Ptr { 49 panic("not a pointer") 50 } 51 valElem := value.Elem() 52 //this loops through the fields 53 for i := 0; i < valElem.NumField(); i++ { // iterates through every struct type field 54 tag := valElem.Type().Field(i).Tag // returns the tag string 55 field := valElem.Field(i) // returns the content of the struct type field 56 switch tag.Get("toml") { 57 case key: 58 if fmt.Sprintf("%v", field.Kind()) == "int" { 59 oldValue = strconv.FormatInt(field.Int(), 10) 60 intVal, err := strconv.Atoi(val) 61 if err != nil { 62 fmt.Printf("could not parse int, key(%s) val(%s)", key, val) 63 } else { 64 field.SetInt(int64(intVal)) 65 } 66 } else if fmt.Sprintf("%v", field.Kind()) == "bool" { 67 oldValue = strconv.FormatBool(field.Bool()) 68 b, err := strconv.ParseBool(val) 69 if err != nil { 70 fmt.Printf("could not parse bool, key(%s) val(%s)", key, val) 71 } else { 72 field.SetBool(b) 73 } 74 } else { 75 // Currently only supports bool, int and string 76 oldValue = field.String() 77 field.SetString(val) 78 } 79 } 80 } 81 return 82 } 83