1package fantasy
2
3import (
4 "encoding/json"
5 "fmt"
6 "sync"
7)
8
9// providerDataJSON is the serialized wrapper used by the registry.
10type providerDataJSON struct {
11 Type string `json:"type"`
12 Data json.RawMessage `json:"data"`
13}
14
15// UnmarshalFunc converts raw JSON into a ProviderOptionsData implementation.
16type UnmarshalFunc func([]byte) (ProviderOptionsData, error)
17
18var (
19 providerRegistry = make(map[string]UnmarshalFunc)
20 registryMutex sync.RWMutex
21)
22
23// RegisterProviderType registers a provider type ID with its unmarshal function.
24// Type IDs must be globally unique (e.g. "openai.options").
25func RegisterProviderType(typeID string, unmarshalFn UnmarshalFunc) {
26 registryMutex.Lock()
27 defer registryMutex.Unlock()
28 providerRegistry[typeID] = unmarshalFn
29}
30
31// unmarshalProviderData routes a typed payload to the correct constructor.
32func unmarshalProviderData(data []byte) (ProviderOptionsData, error) {
33 var pj providerDataJSON
34 if err := json.Unmarshal(data, &pj); err != nil {
35 return nil, err
36 }
37
38 registryMutex.RLock()
39 unmarshalFn, exists := providerRegistry[pj.Type]
40 registryMutex.RUnlock()
41
42 if !exists {
43 return nil, fmt.Errorf("unknown provider data type: %s", pj.Type)
44 }
45
46 return unmarshalFn(pj.Data)
47}
48
49// unmarshalProviderDataMap is a helper for unmarshaling maps of provider data.
50func unmarshalProviderDataMap(data map[string]json.RawMessage) (map[string]ProviderOptionsData, error) {
51 result := make(map[string]ProviderOptionsData)
52 for provider, rawData := range data {
53 providerData, err := unmarshalProviderData(rawData)
54 if err != nil {
55 return nil, fmt.Errorf("failed to unmarshal provider data for %s: %w", provider, err)
56 }
57 result[provider] = providerData
58 }
59 return result, nil
60}
61
62// UnmarshalProviderOptions unmarshals a map of provider options by type.
63func UnmarshalProviderOptions(data map[string]json.RawMessage) (ProviderOptions, error) {
64 return unmarshalProviderDataMap(data)
65}
66
67// UnmarshalProviderMetadata unmarshals a map of provider metadata by type.
68func UnmarshalProviderMetadata(data map[string]json.RawMessage) (ProviderMetadata, error) {
69 return unmarshalProviderDataMap(data)
70}