96 lines
2.0 KiB
Go
96 lines
2.0 KiB
Go
|
|
package formula
|
||
|
|
|
||
|
|
import (
|
||
|
|
"encoding/json"
|
||
|
|
"fmt"
|
||
|
|
"strings"
|
||
|
|
)
|
||
|
|
|
||
|
|
func coerceString(value any) string {
|
||
|
|
switch v := value.(type) {
|
||
|
|
case nil:
|
||
|
|
return ""
|
||
|
|
case string:
|
||
|
|
return strings.TrimSpace(v)
|
||
|
|
case json.Number:
|
||
|
|
return strings.TrimSpace(v.String())
|
||
|
|
case float64:
|
||
|
|
if v == float64(int64(v)) {
|
||
|
|
return fmt.Sprintf("%d", int64(v))
|
||
|
|
}
|
||
|
|
return fmt.Sprintf("%v", v)
|
||
|
|
case bool:
|
||
|
|
if v {
|
||
|
|
return "true"
|
||
|
|
}
|
||
|
|
return "false"
|
||
|
|
case []any:
|
||
|
|
parts := make([]string, 0, len(v))
|
||
|
|
for _, item := range v {
|
||
|
|
if s := coerceString(item); s != "" {
|
||
|
|
parts = append(parts, s)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return strings.Join(parts, " → ")
|
||
|
|
case map[string]any:
|
||
|
|
if text, ok := v["text"].(string); ok {
|
||
|
|
return strings.TrimSpace(text)
|
||
|
|
}
|
||
|
|
b, err := json.Marshal(v)
|
||
|
|
if err != nil {
|
||
|
|
return ""
|
||
|
|
}
|
||
|
|
return strings.TrimSpace(string(b))
|
||
|
|
default:
|
||
|
|
return strings.TrimSpace(fmt.Sprint(v))
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func coerceStringSlice(value any) []string {
|
||
|
|
switch v := value.(type) {
|
||
|
|
case nil:
|
||
|
|
return nil
|
||
|
|
case string:
|
||
|
|
s := strings.TrimSpace(v)
|
||
|
|
if s == "" {
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
return []string{s}
|
||
|
|
case []any:
|
||
|
|
out := make([]string, 0, len(v))
|
||
|
|
for _, item := range v {
|
||
|
|
if s := coerceString(item); s != "" {
|
||
|
|
out = append(out, s)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return out
|
||
|
|
case []string:
|
||
|
|
out := make([]string, 0, len(v))
|
||
|
|
for _, item := range v {
|
||
|
|
if s := strings.TrimSpace(item); s != "" {
|
||
|
|
out = append(out, s)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return out
|
||
|
|
default:
|
||
|
|
if s := coerceString(v); s != "" {
|
||
|
|
return []string{s}
|
||
|
|
}
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func pastedAnalysisFromMap(raw map[string]any) *PastedAnalysis {
|
||
|
|
return &PastedAnalysis{
|
||
|
|
Summary: coerceString(raw["summary"]),
|
||
|
|
Wins: coerceStringSlice(raw["wins"]),
|
||
|
|
Improvements: coerceStringSlice(raw["improvements"]),
|
||
|
|
Formula: coerceString(raw["formula"]),
|
||
|
|
PostTemplate: coerceString(raw["post_template"]),
|
||
|
|
HookPattern: coerceString(raw["hook_pattern"]),
|
||
|
|
Structure: coerceString(raw["structure"]),
|
||
|
|
ReplicationTips: coerceStringSlice(raw["replication_tips"]),
|
||
|
|
Avoid: coerceStringSlice(raw["avoid"]),
|
||
|
|
}
|
||
|
|
}
|