mirror of
https://github.com/taigrr/jety.git
synced 2026-04-01 19:08:58 -07:00
feat(getters): add GetFloat64 and GetInt64, fix docs
- Add GetFloat64 and GetInt64 methods to ConfigManager and package-level API - Fix README precedence: actual order is Set > env > file > default (was incorrectly documented as file > env > default) - Fix GetStringMap return type in API table: map[string]any, not map[string]string - Bump Go to 1.26.1 - Add tests for all new getters (coverage 94.7% → 95.2%)
This commit is contained in:
12
README.md
12
README.md
@@ -15,7 +15,7 @@ Originally built to support [grlx](http://github.com/gogrlx/grlx).
|
|||||||
go get github.com/taigrr/jety
|
go get github.com/taigrr/jety
|
||||||
```
|
```
|
||||||
|
|
||||||
Requires Go 1.26 or later.
|
Requires Go 1.26.1 or later.
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ func main() {
|
|||||||
// handle error
|
// handle error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get values (config file > env > default)
|
// Get values (Set > env > config file > default)
|
||||||
port := jety.GetInt("port")
|
port := jety.GetInt("port")
|
||||||
host := jety.GetString("host")
|
host := jety.GetString("host")
|
||||||
}
|
}
|
||||||
@@ -53,7 +53,7 @@ func main() {
|
|||||||
- **Case-insensitive keys**: Keys normalized to lowercase
|
- **Case-insensitive keys**: Keys normalized to lowercase
|
||||||
- **Type coercion**: Getters handle type conversion gracefully
|
- **Type coercion**: Getters handle type conversion gracefully
|
||||||
- **Thread-safe**: Safe for concurrent access
|
- **Thread-safe**: Safe for concurrent access
|
||||||
- **Config precedence**: config file > environment > defaults
|
- **Config precedence**: Set() > environment > config file > defaults
|
||||||
|
|
||||||
## Nested Configuration
|
## Nested Configuration
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ export MYAPP_PORT=9000
|
|||||||
export MYAPP_SERVICES_CLOUD_VAR=override_value
|
export MYAPP_SERVICES_CLOUD_VAR=override_value
|
||||||
```
|
```
|
||||||
|
|
||||||
**Note**: Environment variables override defaults but config files take highest precedence.
|
**Note**: Environment variables override both defaults and config file values for registered keys (keys that appear in defaults or the config file).
|
||||||
|
|
||||||
## API
|
## API
|
||||||
|
|
||||||
@@ -127,11 +127,13 @@ export MYAPP_SERVICES_CLOUD_VAR=override_value
|
|||||||
| `Get(key)` | Get raw value |
|
| `Get(key)` | Get raw value |
|
||||||
| `GetString(key)` | Get as string |
|
| `GetString(key)` | Get as string |
|
||||||
| `GetInt(key)` | Get as int |
|
| `GetInt(key)` | Get as int |
|
||||||
|
| `GetInt64(key)` | Get as int64 |
|
||||||
|
| `GetFloat64(key)` | Get as float64 |
|
||||||
| `GetBool(key)` | Get as bool |
|
| `GetBool(key)` | Get as bool |
|
||||||
| `GetDuration(key)` | Get as time.Duration |
|
| `GetDuration(key)` | Get as time.Duration |
|
||||||
| `GetStringSlice(key)` | Get as []string |
|
| `GetStringSlice(key)` | Get as []string |
|
||||||
| `GetIntSlice(key)` | Get as []int |
|
| `GetIntSlice(key)` | Get as []int |
|
||||||
| `GetStringMap(key)` | Get as map[string]string |
|
| `GetStringMap(key)` | Get as map[string]any |
|
||||||
| `IsSet(key)` | Check if key has a value |
|
| `IsSet(key)` | Check if key has a value |
|
||||||
| `AllKeys()` | List all known keys |
|
| `AllKeys()` | List all known keys |
|
||||||
| `AllSettings()` | Get all values as a map |
|
| `AllSettings()` | Get all values as a map |
|
||||||
|
|||||||
@@ -20,6 +20,14 @@ func SetConfigName(name string) {
|
|||||||
defaultConfigManager.SetConfigName(name)
|
defaultConfigManager.SetConfigName(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetFloat64(key string) float64 {
|
||||||
|
return defaultConfigManager.GetFloat64(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetInt64(key string) int64 {
|
||||||
|
return defaultConfigManager.GetInt64(key)
|
||||||
|
}
|
||||||
|
|
||||||
func GetInt(key string) int {
|
func GetInt(key string) int {
|
||||||
return defaultConfigManager.GetInt(key)
|
return defaultConfigManager.GetInt(key)
|
||||||
}
|
}
|
||||||
|
|||||||
58
getters.go
58
getters.go
@@ -146,6 +146,64 @@ func (c *ConfigManager) GetStringSlice(key string) []string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *ConfigManager) GetFloat64(key string) float64 {
|
||||||
|
c.mutex.RLock()
|
||||||
|
defer c.mutex.RUnlock()
|
||||||
|
v, ok := c.resolve(key)
|
||||||
|
if !ok {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
switch val := v.Value.(type) {
|
||||||
|
case float64:
|
||||||
|
return val
|
||||||
|
case float32:
|
||||||
|
return float64(val)
|
||||||
|
case int:
|
||||||
|
return float64(val)
|
||||||
|
case int64:
|
||||||
|
return float64(val)
|
||||||
|
case string:
|
||||||
|
f, err := strconv.ParseFloat(val, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return f
|
||||||
|
case nil:
|
||||||
|
return 0
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ConfigManager) GetInt64(key string) int64 {
|
||||||
|
c.mutex.RLock()
|
||||||
|
defer c.mutex.RUnlock()
|
||||||
|
v, ok := c.resolve(key)
|
||||||
|
if !ok {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
switch val := v.Value.(type) {
|
||||||
|
case int64:
|
||||||
|
return val
|
||||||
|
case int:
|
||||||
|
return int64(val)
|
||||||
|
case string:
|
||||||
|
i, err := strconv.ParseInt(val, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return i
|
||||||
|
case float32:
|
||||||
|
return int64(val)
|
||||||
|
case float64:
|
||||||
|
return int64(val)
|
||||||
|
case nil:
|
||||||
|
return 0
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *ConfigManager) GetInt(key string) int {
|
func (c *ConfigManager) GetInt(key string) int {
|
||||||
c.mutex.RLock()
|
c.mutex.RLock()
|
||||||
defer c.mutex.RUnlock()
|
defer c.mutex.RUnlock()
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -1,6 +1,6 @@
|
|||||||
module github.com/taigrr/jety
|
module github.com/taigrr/jety
|
||||||
|
|
||||||
go 1.26.0
|
go 1.26.1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/BurntSushi/toml v1.6.0
|
github.com/BurntSushi/toml v1.6.0
|
||||||
|
|||||||
88
jety_test.go
88
jety_test.go
@@ -120,6 +120,78 @@ func TestSetAndGetInt(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSetAndGetInt64(t *testing.T) {
|
||||||
|
cm := NewConfigManager()
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
value any
|
||||||
|
want int64
|
||||||
|
}{
|
||||||
|
{"int64", int64(9223372036854775807), 9223372036854775807},
|
||||||
|
{"int", 42, 42},
|
||||||
|
{"string", "123456789012345", 123456789012345},
|
||||||
|
{"float64", 99.9, 99},
|
||||||
|
{"float32", float32(50.5), 50},
|
||||||
|
{"invalid string", "not-a-number", 0},
|
||||||
|
{"nil", nil, 0},
|
||||||
|
{"unknown type", struct{}{}, 0},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
cm.Set("key", tt.value)
|
||||||
|
got := cm.GetInt64("key")
|
||||||
|
if got != tt.want {
|
||||||
|
t.Errorf("GetInt64() = %d, want %d", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetAndGetFloat64(t *testing.T) {
|
||||||
|
cm := NewConfigManager()
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
value any
|
||||||
|
want float64
|
||||||
|
}{
|
||||||
|
{"float64", 3.14159, 3.14159},
|
||||||
|
{"float32", float32(2.5), 2.5},
|
||||||
|
{"int", 42, 42.0},
|
||||||
|
{"int64", int64(100), 100.0},
|
||||||
|
{"string", "1.618", 1.618},
|
||||||
|
{"invalid string", "not-a-float", 0},
|
||||||
|
{"nil", nil, 0},
|
||||||
|
{"unknown type", struct{}{}, 0},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
cm.Set("key", tt.value)
|
||||||
|
got := cm.GetFloat64("key")
|
||||||
|
if got != tt.want {
|
||||||
|
t.Errorf("GetFloat64() = %f, want %f", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetFloat64NotSet(t *testing.T) {
|
||||||
|
cm := NewConfigManager()
|
||||||
|
if got := cm.GetFloat64("nonexistent"); got != 0 {
|
||||||
|
t.Errorf("GetFloat64(nonexistent) = %f, want 0", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetInt64NotSet(t *testing.T) {
|
||||||
|
cm := NewConfigManager()
|
||||||
|
if got := cm.GetInt64("nonexistent"); got != 0 {
|
||||||
|
t.Errorf("GetInt64(nonexistent) = %d, want 0", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestSetAndGetBool(t *testing.T) {
|
func TestSetAndGetBool(t *testing.T) {
|
||||||
cm := NewConfigManager()
|
cm := NewConfigManager()
|
||||||
|
|
||||||
@@ -1466,3 +1538,19 @@ func TestPackageLevelGet(t *testing.T) {
|
|||||||
t.Error("Get(key) failed")
|
t.Error("Get(key) failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPackageLevelGetFloat64(t *testing.T) {
|
||||||
|
defaultConfigManager = NewConfigManager()
|
||||||
|
Set("rate", 3.14)
|
||||||
|
if got := GetFloat64("rate"); got != 3.14 {
|
||||||
|
t.Errorf("GetFloat64(rate) = %f, want 3.14", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPackageLevelGetInt64(t *testing.T) {
|
||||||
|
defaultConfigManager = NewConfigManager()
|
||||||
|
Set("bignum", int64(9223372036854775807))
|
||||||
|
if got := GetInt64("bignum"); got != 9223372036854775807 {
|
||||||
|
t.Errorf("GetInt64(bignum) = %d, want 9223372036854775807", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user