1 package encoding
2 3 import (
4 "sync"
5 )
6 7 // Decoder decodes the contents of b into v.
8 // It's primarily used for decoding contents of a file into a map[string]any.
9 type Decoder interface {
10 Decode(b []byte, v map[string]any) error
11 }
12 13 const (
14 // ErrDecoderNotFound is returned when there is no decoder registered for a format.
15 ErrDecoderNotFound = encodingError("decoder not found for this format")
16 17 // ErrDecoderFormatAlreadyRegistered is returned when an decoder is already registered for a format.
18 ErrDecoderFormatAlreadyRegistered = encodingError("decoder already registered for this format")
19 )
20 21 // DecoderRegistry can choose an appropriate Decoder based on the provided format.
22 type DecoderRegistry struct {
23 decoders map[string]Decoder
24 25 mu sync.RWMutex
26 }
27 28 // NewDecoderRegistry returns a new, initialized DecoderRegistry.
29 func NewDecoderRegistry() *DecoderRegistry {
30 return &DecoderRegistry{
31 decoders: make(map[string]Decoder),
32 }
33 }
34 35 // RegisterDecoder registers a Decoder for a format.
36 // Registering a Decoder for an already existing format is not supported.
37 func (e *DecoderRegistry) RegisterDecoder(format string, enc Decoder) error {
38 e.mu.Lock()
39 defer e.mu.Unlock()
40 41 if _, ok := e.decoders[format]; ok {
42 return ErrDecoderFormatAlreadyRegistered
43 }
44 45 e.decoders[format] = enc
46 47 return nil
48 }
49 50 // Decode calls the underlying Decoder based on the format.
51 func (e *DecoderRegistry) Decode(format string, b []byte, v map[string]any) error {
52 e.mu.RLock()
53 decoder, ok := e.decoders[format]
54 e.mu.RUnlock()
55 56 if !ok {
57 return ErrDecoderNotFound
58 }
59 60 return decoder.Decode(b, v)
61 }
62