mirror of
https://github.com/larksuite/cli.git
synced 2026-07-03 14:02:43 +08:00
* feat: add markdown +patch shortcut Change-Id: I8159941ff9dec4e5cbf0c757ec19ee172b302224 * fix: align markdown patch validation and dry-run Change-Id: I98079901e980b74998938afc4917b91a79689948
114 lines
2.5 KiB
Go
114 lines
2.5 KiB
Go
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package common
|
|
|
|
import "github.com/larksuite/cli/internal/util"
|
|
|
|
// GetString safely extracts a string from a nested map path.
|
|
// Usage: GetString(data, "user", "name") is equivalent to
|
|
// data["user"].(map[string]interface{})["name"].(string)
|
|
func GetString(m map[string]interface{}, keys ...string) string {
|
|
if len(keys) == 0 {
|
|
return ""
|
|
}
|
|
v := navigate(m, keys[:len(keys)-1])
|
|
if v == nil {
|
|
return ""
|
|
}
|
|
s, _ := v[keys[len(keys)-1]].(string)
|
|
return s
|
|
}
|
|
|
|
// GetFloat safely extracts a float64 (the default JSON number type).
|
|
func GetFloat(m map[string]interface{}, keys ...string) float64 {
|
|
if len(keys) == 0 {
|
|
return 0
|
|
}
|
|
v := navigate(m, keys[:len(keys)-1])
|
|
if v == nil {
|
|
return 0
|
|
}
|
|
f, _ := util.ToFloat64(v[keys[len(keys)-1]])
|
|
return f
|
|
}
|
|
|
|
// GetInt safely extracts an int, accepting both in-memory ints and JSON-style float64 values.
|
|
func GetInt(m map[string]interface{}, keys ...string) int {
|
|
if len(keys) == 0 {
|
|
return 0
|
|
}
|
|
v := navigate(m, keys[:len(keys)-1])
|
|
if v == nil {
|
|
return 0
|
|
}
|
|
switch n := v[keys[len(keys)-1]].(type) {
|
|
case int:
|
|
return n
|
|
case int64:
|
|
return int(n)
|
|
case float64:
|
|
return int(n)
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// GetBool safely extracts a bool.
|
|
func GetBool(m map[string]interface{}, keys ...string) bool {
|
|
if len(keys) == 0 {
|
|
return false
|
|
}
|
|
v := navigate(m, keys[:len(keys)-1])
|
|
if v == nil {
|
|
return false
|
|
}
|
|
b, _ := v[keys[len(keys)-1]].(bool)
|
|
return b
|
|
}
|
|
|
|
// GetMap safely extracts a nested map.
|
|
func GetMap(m map[string]interface{}, keys ...string) map[string]interface{} {
|
|
if len(keys) == 0 {
|
|
return m
|
|
}
|
|
return navigate(m, keys)
|
|
}
|
|
|
|
// GetSlice safely extracts a []interface{}.
|
|
func GetSlice(m map[string]interface{}, keys ...string) []interface{} {
|
|
if len(keys) == 0 {
|
|
return nil
|
|
}
|
|
v := navigate(m, keys[:len(keys)-1])
|
|
if v == nil {
|
|
return nil
|
|
}
|
|
s, _ := v[keys[len(keys)-1]].([]interface{})
|
|
return s
|
|
}
|
|
|
|
// EachMap iterates over map elements in a slice, skipping non-map items.
|
|
func EachMap(items []interface{}, fn func(m map[string]interface{})) {
|
|
if fn == nil {
|
|
return
|
|
}
|
|
for _, item := range items {
|
|
if m, ok := item.(map[string]interface{}); ok {
|
|
fn(m)
|
|
}
|
|
}
|
|
}
|
|
|
|
// navigate walks a map along the given keys, returning nil if any step fails.
|
|
func navigate(m map[string]interface{}, keys []string) map[string]interface{} {
|
|
cur := m
|
|
for _, k := range keys {
|
|
next, ok := cur[k].(map[string]interface{})
|
|
if !ok {
|
|
return nil
|
|
}
|
|
cur = next
|
|
}
|
|
return cur
|
|
}
|