decoder.go (1618B)
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]interface{}. 9 type Decoder interface { 10 Decode(b []byte, v map[string]interface{}) 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]interface{}) 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 }