provider_registry.go

 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}