-
Notifications
You must be signed in to change notification settings - Fork 1
/
bs.go
82 lines (69 loc) · 1.59 KB
/
bs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package bs
import (
"bytes"
"crypto/sha256"
"database/sql/driver"
"encoding/hex"
"errors"
"fmt"
)
type (
// Blob is a data blob.
Blob []byte
// Ref is the reference of a blob: its sha256 hash.
Ref [sha256.Size]byte
)
// Zero is the zero ref.
var Zero Ref
// Ref computes the Ref of a blob.
func (b Blob) Ref() Ref {
return sha256.Sum256(b)
}
// String converts a Ref to a hexadecimal string.
func (r Ref) String() string {
return hex.EncodeToString(r[:])
}
// Less tells whether `r` is lexicographically less than `other`.
func (r Ref) Less(other Ref) bool {
return bytes.Compare(r[:], other[:]) < 0
}
// IsZero tells whether r is the zero ref.
func (r Ref) IsZero() bool {
return r == Ref{}
}
// FromHex parses the hex string `s` and places the result in `r`.
func (r *Ref) FromHex(s string) error {
if len(s) != 2*sha256.Size {
return errors.New("wrong length")
}
_, err := hex.Decode(r[:], []byte(s))
return err
}
// RefFromBytes produces a Ref from a byte slice.
// The length of the byte slice is not checked.
func RefFromBytes(b []byte) Ref {
var out Ref
copy(out[:], b)
return out
}
// RefFromHex produces a Ref from a hex string.
func RefFromHex(s string) (Ref, error) {
var out Ref
err := out.FromHex(s)
return out, err
}
// Value implements the "database/sql".Valuer.
func (r Ref) Value() (driver.Value, error) {
return r[:], nil
}
// Scan implements the "database/sql".Scanner.
func (r *Ref) Scan(src interface{}) error {
if src == nil {
return nil
}
if b, ok := src.([]byte); ok {
copy((*r)[:], b)
return nil
}
return fmt.Errorf("cannot scan %T into *Ref", src)
}