Bootstrapped during the 2026-06-06 BlockNinja consolidation. Was previously an unversioned directory inside ~/src/blockninja-themes/scifi-clean. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
83 lines
2.0 KiB
Go
83 lines
2.0 KiB
Go
package main
|
|
|
|
// getString extracts a string value from a content map.
|
|
func getString(content map[string]any, key string) string {
|
|
if v, ok := content[key].(string); ok {
|
|
return v
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// getStringDefault returns the string at key, falling back to def if missing/blank.
|
|
func getStringDefault(content map[string]any, key, def string) string {
|
|
if v := getString(content, key); v != "" {
|
|
return v
|
|
}
|
|
return def
|
|
}
|
|
|
|
// getBool extracts a boolean from a content map. Accepts native bool, string ("true"/"1"),
|
|
// or numeric truthiness. Returns def when no value is present or parseable.
|
|
func getBool(content map[string]any, key string, def bool) bool {
|
|
if v, ok := content[key]; ok {
|
|
switch t := v.(type) {
|
|
case bool:
|
|
return t
|
|
case string:
|
|
switch t {
|
|
case "true", "TRUE", "True", "1", "yes", "on":
|
|
return true
|
|
case "false", "FALSE", "False", "0", "no", "off":
|
|
return false
|
|
}
|
|
case float64:
|
|
return t != 0
|
|
case int:
|
|
return t != 0
|
|
}
|
|
}
|
|
return def
|
|
}
|
|
|
|
// getSlice extracts a slice of maps from content under key. Returns nil if not a slice.
|
|
func getSlice(content map[string]any, key string) []map[string]any {
|
|
if v, ok := content[key].([]any); ok {
|
|
out := make([]map[string]any, 0, len(v))
|
|
for _, item := range v {
|
|
if m, ok := item.(map[string]any); ok {
|
|
out = append(out, m)
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// getMap returns the map at key, or nil.
|
|
func getMap(content map[string]any, key string) map[string]any {
|
|
if m, ok := content[key].(map[string]any); ok {
|
|
return m
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// getFloat returns the float at key, or def if missing / wrong type.
|
|
func getFloat(content map[string]any, key string, def float64) float64 {
|
|
if v, ok := content[key].(float64); ok {
|
|
return v
|
|
}
|
|
if v, ok := content[key].(int); ok {
|
|
return float64(v)
|
|
}
|
|
return def
|
|
}
|
|
|
|
// normalizeTrend coerces an incoming trend string to {up, down, flat}, defaulting to flat.
|
|
func normalizeTrend(s string) string {
|
|
switch s {
|
|
case "up", "down", "flat":
|
|
return s
|
|
}
|
|
return "flat"
|
|
}
|