package config import ( "slices" "strings" ) func (c *Config) ReconcileCredentials(base Config) { if c == nil { return } currKeys := normalizeKeys(c.Keys) currAPIKeys := normalizeAPIKeys(c.APIKeys) baseKeys := normalizeKeys(base.Keys) baseAPIKeys := normalizeAPIKeys(base.APIKeys) keysChanged := !slices.Equal(currKeys, baseKeys) apiKeysChanged := !equalAPIKeys(currAPIKeys, baseAPIKeys) if keysChanged && !apiKeysChanged { c.APIKeys = apiKeysFromStrings(currKeys, apiKeyMap(baseAPIKeys)) } else { c.APIKeys = currAPIKeys } c.Keys = apiKeysToStrings(c.APIKeys) } func normalizeKeys(keys []string) []string { if len(keys) == 0 { return nil } out := make([]string, 0, len(keys)) seen := make(map[string]struct{}, len(keys)) for _, key := range keys { key = strings.TrimSpace(key) if key == "" { continue } if _, ok := seen[key]; ok { continue } seen[key] = struct{}{} out = append(out, key) } if len(out) == 0 { return nil } return out } func normalizeAPIKeys(items []APIKey) []APIKey { if len(items) == 0 { return nil } out := make([]APIKey, 0, len(items)) seen := make(map[string]struct{}, len(items)) for _, item := range items { key := strings.TrimSpace(item.Key) if key == "" { continue } if _, ok := seen[key]; ok { continue } seen[key] = struct{}{} out = append(out, APIKey{ Key: key, Name: strings.TrimSpace(item.Name), Remark: strings.TrimSpace(item.Remark), }) } if len(out) == 0 { return nil } return out } func apiKeysFromStrings(keys []string, meta map[string]APIKey) []APIKey { if len(keys) == 0 { return nil } out := make([]APIKey, 0, len(keys)) seen := make(map[string]struct{}, len(keys)) for _, key := range keys { key = strings.TrimSpace(key) if key == "" { continue } if _, ok := seen[key]; ok { continue } seen[key] = struct{}{} if item, ok := meta[key]; ok { out = append(out, APIKey{ Key: key, Name: strings.TrimSpace(item.Name), Remark: strings.TrimSpace(item.Remark), }) continue } out = append(out, APIKey{Key: key}) } if len(out) == 0 { return nil } return out } func apiKeysToStrings(items []APIKey) []string { if len(items) == 0 { return nil } keys := make([]string, 0, len(items)) for _, item := range items { key := strings.TrimSpace(item.Key) if key == "" { continue } keys = append(keys, key) } if len(keys) == 0 { return nil } return keys } func apiKeyMap(items []APIKey) map[string]APIKey { if len(items) == 0 { return nil } out := make(map[string]APIKey, len(items)) for _, item := range items { key := strings.TrimSpace(item.Key) if key == "" { continue } if _, ok := out[key]; ok { continue } out[key] = APIKey{ Key: key, Name: strings.TrimSpace(item.Name), Remark: strings.TrimSpace(item.Remark), } } return out } func equalAPIKeys(a, b []APIKey) bool { if len(a) != len(b) { return false } return slices.EqualFunc(a, b, func(x, y APIKey) bool { return strings.TrimSpace(x.Key) == strings.TrimSpace(y.Key) && strings.TrimSpace(x.Name) == strings.TrimSpace(y.Name) && strings.TrimSpace(x.Remark) == strings.TrimSpace(y.Remark) }) }