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