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

Łukasz Magiera's avatar
Łukasz Magiera committed
3
import (
4
	"fmt"
Łukasz Magiera's avatar
Łukasz Magiera committed
5 6
	cid "github.com/ipfs/go-cid"
	mh "github.com/multiformats/go-multihash"
Ł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
	MhType   uint64
	MhLength int
Łukasz Magiera's avatar
Łukasz Magiera committed
13
	Pin      bool
Łukasz Magiera's avatar
Łukasz Magiera committed
14 15 16 17 18 19 20 21
}

type BlockRmSettings struct {
	Force bool
}

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

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

	for _, opt := range opts {
		err := opt(options)
		if err != nil {
34
			return nil, cid.Prefix{}, err
Łukasz Magiera's avatar
Łukasz Magiera committed
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 68 69

	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
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
}

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
}

86
type blockOpts struct{}
Łukasz Magiera's avatar
Łukasz Magiera committed
87

88 89 90 91
var Block blockOpts

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

99 100 101
// 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
102
func (blockOpts) Hash(mhType uint64, mhLen int) BlockPutOption {
Łukasz Magiera's avatar
Łukasz Magiera committed
103 104 105 106 107 108 109
	return func(settings *BlockPutSettings) error {
		settings.MhType = mhType
		settings.MhLength = mhLen
		return nil
	}
}

Łukasz Magiera's avatar
Łukasz Magiera committed
110 111 112 113 114 115 116 117 118
// Pin is an option for Block.Put which specifies whether to (recursively) pin
// added blocks
func (blockOpts) Pin(pin bool) BlockPutOption {
	return func(settings *BlockPutSettings) error {
		settings.Pin = pin
		return nil
	}
}

119 120
// Force is an option for Block.Rm which, when set to true, will ignore
// non-existing blocks
121
func (blockOpts) Force(force bool) BlockRmOption {
Łukasz Magiera's avatar
Łukasz Magiera committed
122 123 124 125 126
	return func(settings *BlockRmSettings) error {
		settings.Force = force
		return nil
	}
}