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 extracts a string with a fallback. func getStringDefault(content map[string]any, key, def string) string { if v, ok := content[key].(string); ok && v != "" { return v } return def } // getInt extracts an int (handles JSON float64). func getInt(content map[string]any, key string, defaultVal int) int { if v, ok := content[key].(float64); ok { return int(v) } if v, ok := content[key].(int); ok { return v } return defaultVal } // getBool extracts a bool (handles string "true"/"false" too). func getBool(content map[string]any, key string) bool { if v, ok := content[key].(bool); ok { return v } if v, ok := content[key].(string); ok { return v == "true" || v == "yes" || v == "1" } return false } // getSlice extracts a slice of maps from content. func getSlice(content map[string]any, key string) []map[string]any { if v, ok := content[key].([]any); ok { result := make([]map[string]any, 0, len(v)) for _, item := range v { if m, ok := item.(map[string]any); ok { result = append(result, m) } } return result } return nil } // getStringSlice extracts a flat slice of strings (e.g. boot_log lines). // Tolerates non-string entries by converting fmt.Sprint-style; missing keys // or wrong types yield an empty slice (no panic). func getStringSlice(content map[string]any, key string) []string { v, ok := content[key].([]any) if !ok { return nil } out := make([]string, 0, len(v)) for _, item := range v { switch s := item.(type) { case string: out = append(out, s) case nil: out = append(out, "") default: out = append(out, "") } } return out }