1/* 2 Package config is a simple tool to handle key-value config, like Redis's configuration: 3 4 # commet 5 key = value 6 7*/ 8package config 9 10import ( 11 "errors" 12 "fmt" 13 "strconv" 14 "strings" 15) 16 17var ( 18 ErrNil = errors.New("nil value") 19) 20 21type Config struct { 22 Values map[string]string 23} 24 25func NewConfig() *Config { 26 c := &Config{} 27 c.Values = make(map[string]string) 28 return c 29} 30 31/* 32 bool: true, false, 0, 1, or "" 33*/ 34func (c *Config) GetBool(key string) (bool, error) { 35 v, err := c.GetString(key) 36 if err != nil { 37 return false, err 38 } 39 40 v = strings.ToLower(v) 41 switch v { 42 case "true", "1": 43 return true, nil 44 case "false", "0", "": 45 return false, nil 46 default: 47 return false, fmt.Errorf("invalid bool format %s", v) 48 } 49} 50 51/* 52 int may be pure number or below format: 53 54 # 1k => 1000 bytes 55 # 1kb => 1024 bytes 56 # 1m => 1000000 bytes 57 # 1mb => 1024*1024 bytes 58 # 1g => 1000000000 bytes 59 # 1gb => 1024*1024*1024 bytes 60 61*/ 62func (c *Config) GetInt64(key string) (int64, error) { 63 v, err := c.GetString(key) 64 if err != nil { 65 return 0, err 66 } 67 68 if len(v) == 0 { 69 return 0, ErrNil 70 } 71 72 var scale int64 = 1 73 v = strings.ToLower(v) 74 75 var b bool = false 76 if v[len(v)-1] == 'b' { 77 v = v[0 : len(v)-1] 78 b = true 79 } 80 81 if len(v) == 0 { 82 return 0, fmt.Errorf("invalid number format %s", v) 83 } 84 85 switch v[len(v)-1] { 86 case 'k': 87 v = v[0 : len(v)-1] 88 if b { 89 scale = 1024 90 } else { 91 scale = 1000 92 } 93 break 94 case 'm': 95 v = v[0 : len(v)-1] 96 if b { 97 scale = 1024 * 1024 98 } else { 99 scale = 1000 * 1000 100 } 101 case 'g': 102 v = v[0 : len(v)-1] 103 if b { 104 scale = 1024 * 1024 * 1024 105 } else { 106 scale = 1000 * 1000 * 1000 107 } 108 } 109 110 var n int64 111 n, err = strconv.ParseInt(v, 10, 64) 112 if err != nil { 113 return 0, err 114 } 115 116 return n * scale, nil 117} 118 119func (c *Config) GetUint64(key string) (uint64, error) { 120 v, err := c.GetInt64(key) 121 if v < 0 { 122 return 0, fmt.Errorf("negative number %d", v) 123 } 124 return uint64(v), err 125} 126 127func (c *Config) GetInt(key string) (int, error) { 128 v, err := c.GetInt64(key) 129 return int(v), err 130} 131 132func (c *Config) GetString(key string) (string, error) { 133 v, ok := c.Values[key] 134 if !ok { 135 return "", ErrNil 136 } else { 137 return v, nil 138 } 139} 140 141func (c *Config) SetString(key string, value string) { 142 c.Values[key] = value 143} 144 145func (c *Config) SetInt64(key string, n int64) { 146 c.Values[key] = strconv.FormatInt(n, 10) 147} 148 149func (c *Config) SetUint64(key string, n uint64) { 150 c.Values[key] = strconv.FormatUint(n, 10) 151} 152 153func (c *Config) SetInt(key string, n int) { 154 c.SetInt64(key, int64(n)) 155} 156 157func (c *Config) SetBool(key string, v bool) { 158 if v { 159 c.Values[key] = "true" 160 } else { 161 c.Values[key] = "false" 162 } 163} 164