-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make a multicodec.Registry type available.
The hope is that this might be helpful if you want to build a multicodec registry other than the global one, but are still buying into the idea of the registry being keyed by indicator numbers. The current interfaces are functionally unchanged. This type can now be used when constructing a cidlink.LinkSystem. I considered a mechanism like: `func (r *Registry) InstallOn(lsys *ipld.LinkSystem)` ... and probably would've found that a bit cleaner. However, it doesn't jive with the way we've isolated the CID types into a package with a LinkSystem just for them (sigh; that really is the gift of complexity that just keeps giving); you can see how the EncoderChooser and DecoderChooser funcs need a tiny bit of type assertions in order to figure out how to extract the multicodec indicator from the Link/LinkPrototype types? That bit is a bit that we still want to keep cordoned off the rest of the import tree. I probably would've preferred to keep the DefaultRegistry variable unexported, because I can't imagine any good coming of touching it, but again, the above paragraph forced my hand.
- Loading branch information
Showing
3 changed files
with
89 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package multicodec | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/ipld/go-ipld-prime" | ||
) | ||
|
||
// Registry is a structure for storing mappings of multicodec indiactor numbers to ipld.Encoder and ipld.Decoder functions. | ||
// | ||
// The most typical usage of this structure is in combination with an ipld.LinkSystem. | ||
// For example, a linksystem using CIDs and a custom multicodec registry can be constructed | ||
// using cidlink.LinkSystemUsingMulticodecRegistry. | ||
// | ||
// go-ipld-prime also has a default registry, which has the same methods as this structure, but are at package scope. | ||
// Some systems, like cidlink.DefaultLinkSystem, will use this default registry. | ||
// This Registry type is for helping if you wish to make your own registry which does not share that global state. | ||
// | ||
// Multicodec indicator numbers are specified in | ||
// https://github.com/multiformats/multicodec/blob/master/table.csv . | ||
// You should not use indicator numbers which are not specified in that table | ||
// (however, there is nothing in this implementation that will attempt to stop you, either; please behave). | ||
type Registry struct { | ||
encoders map[uint64]ipld.Encoder | ||
decoders map[uint64]ipld.Decoder | ||
} | ||
|
||
func (r *Registry) ensureInit() { | ||
if r.encoders != nil { | ||
return | ||
} | ||
r.encoders = make(map[uint64]ipld.Encoder) | ||
r.decoders = make(map[uint64]ipld.Decoder) | ||
} | ||
|
||
// RegisterEncoder updates a simple map of multicodec indicator number to ipld.Encoder function. | ||
// The encoder functions registered can be subsequently looked up using LookupEncoder. | ||
func (r *Registry) RegisterEncoder(indicator uint64, encodeFunc ipld.Encoder) { | ||
r.ensureInit() | ||
if encodeFunc == nil { | ||
panic("not sensible to attempt to register a nil function") | ||
} | ||
r.encoders[indicator] = encodeFunc | ||
} | ||
|
||
// LookupEncoder yields an ipld.Encoder function matching a multicodec indicator code number. | ||
// | ||
// To be available from this lookup function, an encoder must have been registered | ||
// for this indicator number by an earlier call to the RegisterEncoder function. | ||
func (r *Registry) LookupEncoder(indicator uint64) (ipld.Encoder, error) { | ||
encodeFunc, exists := r.encoders[indicator] | ||
if !exists { | ||
return nil, fmt.Errorf("no encoder registered for multicodec code %d (0x%x)", indicator, indicator) | ||
} | ||
return encodeFunc, nil | ||
} | ||
|
||
// RegisterDecoder updates a simple map of multicodec indicator number to ipld.Decoder function. | ||
// The decoder functions registered can be subsequently looked up using LookupDecoder. | ||
func (r *Registry) RegisterDecoder(indicator uint64, decodeFunc ipld.Decoder) { | ||
r.ensureInit() | ||
if decodeFunc == nil { | ||
panic("not sensible to attempt to register a nil function") | ||
} | ||
r.decoders[indicator] = decodeFunc | ||
} | ||
|
||
// LookupDecoder yields an ipld.Decoder function matching a multicodec indicator code number. | ||
// | ||
// To be available from this lookup function, an decoder must have been registered | ||
// for this indicator number by an earlier call to the RegisterDecoder function. | ||
func (r *Registry) LookupDecoder(indicator uint64) (ipld.Decoder, error) { | ||
decodeFunc, exists := r.decoders[indicator] | ||
if !exists { | ||
return nil, fmt.Errorf("no decoder registered for multicodec code %d (0x%x)", indicator, indicator) | ||
} | ||
return decodeFunc, nil | ||
} |