block.go 2.6 KB
Newer Older
Łukasz Magiera's avatar
Łukasz Magiera committed
1 2
package options

Łukasz Magiera's avatar
Łukasz Magiera committed
3
import (
4 5 6
	"fmt"
	mh "gx/ipfs/QmPnFwZ2JXKnXgMw8CdBPxn7FWh6LLdjUjxV1fKHuJnkr8/go-multihash"
	cid "gx/ipfs/QmZFbDTY9jfSBms2MchvYM9oYRbAF19K7Pby47yDBfpPrb/go-cid"
Łukasz Magiera's avatar
Łukasz Magiera committed
7 8
)

Łukasz Magiera's avatar
Łukasz Magiera committed
9
type BlockPutSettings struct {
Łukasz Magiera's avatar
Łukasz Magiera committed
10
	Codec    string
Łukasz Magiera's avatar
Łukasz Magiera committed
11 12 13 14 15 16 17 18 19 20
	MhType   uint64
	MhLength int
}

type BlockRmSettings struct {
	Force bool
}

type BlockPutOption func(*BlockPutSettings) error
type BlockRmOption func(*BlockRmSettings) error
Łukasz Magiera's avatar
Łukasz Magiera committed
21

22
func BlockPutOptions(opts ...BlockPutOption) (*BlockPutSettings, cid.Prefix, error) {
Łukasz Magiera's avatar
Łukasz Magiera committed
23
	options := &BlockPutSettings{
24
		Codec:    "",
25
		MhType:   mh.SHA2_256,
Łukasz Magiera's avatar
Łukasz Magiera committed
26 27 28 29 30 31
		MhLength: -1,
	}

	for _, opt := range opts {
		err := opt(options)
		if err != nil {
32
			return nil, cid.Prefix{}, err
Łukasz Magiera's avatar
Łukasz Magiera committed
33 34
		}
	}
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67

	var pref cid.Prefix
	pref.Version = 1

	if options.Codec == "" {
		if options.MhType != mh.SHA2_256 || (options.MhLength != -1 && options.MhLength != 32) {
			options.Codec = "protobuf"
		} else {
			options.Codec = "v0"
		}
	}

	if options.Codec == "v0" && options.MhType == mh.SHA2_256 {
		pref.Version = 0
	}

	formatval, ok := cid.Codecs[options.Codec]
	if !ok {
		return nil, cid.Prefix{}, fmt.Errorf("unrecognized format: %s", options.Codec)
	}

	if options.Codec == "v0" {
		if options.MhType != mh.SHA2_256 || (options.MhLength != -1 && options.MhLength != 32) {
			return nil, cid.Prefix{}, fmt.Errorf("only sha2-255-32 is allowed with CIDv0")
		}
	}

	pref.Codec = formatval

	pref.MhType = options.MhType
	pref.MhLength = options.MhLength

	return options, pref, nil
Łukasz Magiera's avatar
Łukasz Magiera committed
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
}

func BlockRmOptions(opts ...BlockRmOption) (*BlockRmSettings, error) {
	options := &BlockRmSettings{
		Force: false,
	}

	for _, opt := range opts {
		err := opt(options)
		if err != nil {
			return nil, err
		}
	}
	return options, nil
}

84
type blockOpts struct{}
Łukasz Magiera's avatar
Łukasz Magiera committed
85

86 87 88 89
var Block blockOpts

// Format is an option for Block.Put which specifies the multicodec to use to
// serialize the object. Default is "v0"
90
func (blockOpts) Format(codec string) BlockPutOption {
Łukasz Magiera's avatar
Łukasz Magiera committed
91 92 93 94 95 96
	return func(settings *BlockPutSettings) error {
		settings.Codec = codec
		return nil
	}
}

97 98 99
// Hash is an option for Block.Put which specifies the multihash settings to use
// when hashing the object. Default is mh.SHA2_256 (0x12).
// If mhLen is set to -1, default length for the hash will be used
100
func (blockOpts) Hash(mhType uint64, mhLen int) BlockPutOption {
Łukasz Magiera's avatar
Łukasz Magiera committed
101 102 103 104 105 106 107
	return func(settings *BlockPutSettings) error {
		settings.MhType = mhType
		settings.MhLength = mhLen
		return nil
	}
}

108 109
// Force is an option for Block.Rm which, when set to true, will ignore
// non-existing blocks
110
func (blockOpts) Force(force bool) BlockRmOption {
Łukasz Magiera's avatar
Łukasz Magiera committed
111 112 113 114 115
	return func(settings *BlockRmSettings) error {
		settings.Force = force
		return nil
	}
}