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  }