github.com/ipld/go-ipld-prime@v0.21.0/multicodec/registry.go (about) 1 package multicodec 2 3 import ( 4 "fmt" 5 6 "github.com/ipld/go-ipld-prime/codec" 7 ) 8 9 // Registry is a structure for storing mappings of multicodec indicator numbers to codec.Encoder and codec.Decoder functions. 10 // 11 // The most typical usage of this structure is in combination with a codec.LinkSystem. 12 // For example, a linksystem using CIDs and a custom multicodec registry can be constructed 13 // using cidlink.LinkSystemUsingMulticodecRegistry. 14 // 15 // Registry includes no mutexing. If using Registry in a concurrent context, you must handle synchronization yourself. 16 // (Typically, it is recommended to do initialization earlier in a program, before fanning out goroutines; 17 // this avoids the need for mutexing overhead.) 18 // 19 // go-ipld also has a default registry, which has the same methods as this structure, but are at package scope. 20 // Some systems, like cidlink.DefaultLinkSystem, will use this default registry. 21 // However, this default registry is global to the entire program. 22 // This Registry type is for helping if you wish to make your own registry which does not share that global state. 23 // 24 // Multicodec indicator numbers are specified in 25 // https://github.com/multiformats/multicodec/blob/master/table.csv . 26 // You should not use indicator numbers which are not specified in that table 27 // (however, there is nothing in this implementation that will attempt to stop you, either; please behave). 28 type Registry struct { 29 encoders map[uint64]codec.Encoder 30 decoders map[uint64]codec.Decoder 31 } 32 33 func (r *Registry) ensureInit() { 34 if r.encoders != nil { 35 return 36 } 37 r.encoders = make(map[uint64]codec.Encoder) 38 r.decoders = make(map[uint64]codec.Decoder) 39 } 40 41 // RegisterEncoder updates a simple map of multicodec indicator number to codec.Encoder function. 42 // The encoder functions registered can be subsequently looked up using LookupEncoder. 43 func (r *Registry) RegisterEncoder(indicator uint64, encodeFunc codec.Encoder) { 44 r.ensureInit() 45 if encodeFunc == nil { 46 panic("not sensible to attempt to register a nil function") 47 } 48 r.encoders[indicator] = encodeFunc 49 } 50 51 // LookupEncoder yields a codec.Encoder function matching a multicodec indicator code number. 52 // 53 // To be available from this lookup function, an encoder must have been registered 54 // for this indicator number by an earlier call to the RegisterEncoder function. 55 func (r *Registry) LookupEncoder(indicator uint64) (codec.Encoder, error) { 56 encodeFunc, exists := r.encoders[indicator] 57 if !exists { 58 return nil, fmt.Errorf("no encoder registered for multicodec code %d (0x%x)", indicator, indicator) 59 } 60 return encodeFunc, nil 61 } 62 63 // ListEncoders returns a list of multicodec indicators for which a codec.Encoder is registered. 64 // The list is in no particular order. 65 func (r *Registry) ListEncoders() []uint64 { 66 encoders := make([]uint64, 0, len(r.encoders)) 67 for e := range r.encoders { 68 encoders = append(encoders, e) 69 } 70 return encoders 71 } 72 73 // TODO(mvdan): turn most of these uint64s into multicodec.Code 74 75 // RegisterDecoder updates a simple map of multicodec indicator number to codec.Decoder function. 76 // The decoder functions registered can be subsequently looked up using LookupDecoder. 77 func (r *Registry) RegisterDecoder(indicator uint64, decodeFunc codec.Decoder) { 78 r.ensureInit() 79 if decodeFunc == nil { 80 panic("not sensible to attempt to register a nil function") 81 } 82 r.decoders[indicator] = decodeFunc 83 } 84 85 // LookupDecoder yields a codec.Decoder function matching a multicodec indicator code number. 86 // 87 // To be available from this lookup function, an decoder must have been registered 88 // for this indicator number by an earlier call to the RegisterDecoder function. 89 func (r *Registry) LookupDecoder(indicator uint64) (codec.Decoder, error) { 90 decodeFunc, exists := r.decoders[indicator] 91 if !exists { 92 return nil, fmt.Errorf("no decoder registered for multicodec code %d (0x%x)", indicator, indicator) 93 } 94 return decodeFunc, nil 95 } 96 97 // ListDecoders returns a list of multicodec indicators for which a codec.Decoder is registered. 98 // The list is in no particular order. 99 func (r *Registry) ListDecoders() []uint64 { 100 decoders := make([]uint64, 0, len(r.decoders)) 101 for d := range r.decoders { 102 decoders = append(decoders, d) 103 } 104 return decoders 105 }