Files
descrybe/apps/api/internal/eprel/id.go
T
greeneclipse 8580c996c3 Initial commit of Descrybe v2 without local scratch artifacts.
Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
2026-08-09 22:47:43 +02:00

96 lines
1.9 KiB
Go

package eprel
import (
"encoding/json"
"fmt"
"strconv"
"strings"
)
var eprelIDKeys = []string{
"eprel_id",
"EPRELID",
"eprelId",
"EprelId",
"eprelID",
}
// NormalizeID coerces XML/API values (string, number, {"#text": ...}) to a trimmed ID.
func NormalizeID(v any) string {
if v == nil {
return ""
}
switch t := v.(type) {
case string:
return strings.TrimSpace(t)
case json.Number:
s := strings.TrimSpace(t.String())
if i := strings.IndexByte(s, '.'); i >= 0 {
s = s[:i]
}
return s
case float64:
if t != t { // NaN
return ""
}
return strconv.FormatInt(int64(t), 10)
case float32:
return strconv.FormatInt(int64(t), 10)
case int:
return strconv.Itoa(t)
case int64:
return strconv.FormatInt(t, 10)
case int32:
return strconv.FormatInt(int64(t), 10)
case json.RawMessage:
var decoded any
if err := json.Unmarshal(t, &decoded); err != nil {
return ""
}
return NormalizeID(decoded)
case map[string]any:
if text, ok := t["#text"]; ok {
return NormalizeID(text)
}
if text, ok := t["text"]; ok {
return NormalizeID(text)
}
default:
s := strings.TrimSpace(fmt.Sprint(t))
if s == "" || s == "<nil>" {
return ""
}
return s
}
return ""
}
// IsValidID reports whether v normalizes to a non-empty EPREL registration id.
func IsValidID(v any) bool {
return NormalizeID(v) != ""
}
// ExtractID finds an EPREL ID in mapped and/or raw product field maps
// (vendor feeds often use <EPRELID/> / eprel_id).
func ExtractID(sources ...map[string]any) string {
for _, src := range sources {
if src == nil {
continue
}
for _, key := range eprelIDKeys {
if id := NormalizeID(src[key]); id != "" {
return id
}
}
for key, value := range src {
compact := strings.ToLower(strings.ReplaceAll(key, "_", ""))
if compact == "eprelid" {
if id := NormalizeID(value); id != "" {
return id
}
}
}
}
return ""
}