github.com/ipld/go-ipld-prime@v0.21.0/linking/cid/linksystem.go (about) 1 package cidlink 2 3 import ( 4 "fmt" 5 "hash" 6 7 multihash "github.com/multiformats/go-multihash/core" 8 9 "github.com/ipld/go-ipld-prime/codec" 10 "github.com/ipld/go-ipld-prime/datamodel" 11 "github.com/ipld/go-ipld-prime/linking" 12 "github.com/ipld/go-ipld-prime/multicodec" 13 ) 14 15 // DefaultLinkSystem returns a linking.LinkSystem which uses cidlink.Link for datamodel.Link. 16 // During selection of encoders, decoders, and hashers, it examines the multicodec indicator numbers and multihash indicator numbers from the CID, 17 // and uses the default global multicodec registry (see the go-ipld-prime/multicodec package) for resolving codec implementations, 18 // and the default global multihash registry (see the go-multihash/core package) for resolving multihash implementations. 19 // 20 // No storage functions are present in the returned LinkSystem. 21 // The caller can assign those themselves as desired. 22 func DefaultLinkSystem() linking.LinkSystem { 23 return LinkSystemUsingMulticodecRegistry(multicodec.DefaultRegistry) 24 } 25 26 // LinkSystemUsingMulticodecRegistry is similar to DefaultLinkSystem, but accepts a multicodec.Registry as a parameter. 27 // 28 // This can help create a LinkSystem which uses different multicodec implementations than the global registry. 29 // (Sometimes this can be desired if you want some parts of a program to support a more limited suite of codecs than other parts of the program, 30 // or needed to use a different multicodec registry than the global one for synchronization purposes, or etc.) 31 func LinkSystemUsingMulticodecRegistry(mcReg multicodec.Registry) linking.LinkSystem { 32 return linking.LinkSystem{ 33 EncoderChooser: func(lp datamodel.LinkPrototype) (codec.Encoder, error) { 34 switch lp2 := lp.(type) { 35 case LinkPrototype: 36 fn, err := mcReg.LookupEncoder(lp2.GetCodec()) 37 if err != nil { 38 return nil, err 39 } 40 return fn, nil 41 default: 42 return nil, fmt.Errorf("this encoderChooser can only handle cidlink.LinkPrototype; got %T", lp) 43 } 44 }, 45 DecoderChooser: func(lnk datamodel.Link) (codec.Decoder, error) { 46 lp := lnk.Prototype() 47 switch lp2 := lp.(type) { 48 case LinkPrototype: 49 fn, err := mcReg.LookupDecoder(lp2.GetCodec()) 50 if err != nil { 51 return nil, err 52 } 53 return fn, nil 54 default: 55 return nil, fmt.Errorf("this decoderChooser can only handle cidlink.LinkPrototype; got %T", lp) 56 } 57 }, 58 HasherChooser: func(lp datamodel.LinkPrototype) (hash.Hash, error) { 59 switch lp2 := lp.(type) { 60 case LinkPrototype: 61 h, err := multihash.GetHasher(lp2.MhType) 62 if err != nil { 63 return nil, fmt.Errorf("no hasher registered for multihash indicator 0x%x: %w", lp2.MhType, err) 64 } 65 return h, nil 66 default: 67 return nil, fmt.Errorf("this hasherChooser can only handle cidlink.LinkPrototype; got %T", lp) 68 } 69 }, 70 } 71 }