53 lines
866 B
Go
53 lines
866 B
Go
|
package build
|
||
|
|
||
|
import (
|
||
|
"crypto/rand"
|
||
|
"crypto/sha1"
|
||
|
"encoding"
|
||
|
"encoding/hex"
|
||
|
"fmt"
|
||
|
"path/filepath"
|
||
|
)
|
||
|
|
||
|
type ID [sha1.Size]byte
|
||
|
|
||
|
var (
|
||
|
_ = encoding.TextMarshaler(ID{})
|
||
|
_ = encoding.TextUnmarshaler(&ID{})
|
||
|
)
|
||
|
|
||
|
func (id ID) String() string {
|
||
|
return hex.EncodeToString(id[:])
|
||
|
}
|
||
|
|
||
|
func (id ID) Path() string {
|
||
|
return filepath.Join(hex.EncodeToString(id[:1]), hex.EncodeToString(id[:]))
|
||
|
}
|
||
|
|
||
|
func (id ID) MarshalText() ([]byte, error) {
|
||
|
return []byte(hex.EncodeToString(id[:])), nil
|
||
|
}
|
||
|
|
||
|
func (id *ID) UnmarshalText(b []byte) error {
|
||
|
raw, err := hex.DecodeString(string(b))
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
if len(raw) != len(id) {
|
||
|
return fmt.Errorf("invalid id size: %q", b)
|
||
|
}
|
||
|
|
||
|
copy(id[:], raw)
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func NewID() ID {
|
||
|
var id ID
|
||
|
_, err := rand.Read(id[:])
|
||
|
if err != nil {
|
||
|
panic(fmt.Sprintf("crypto/rand is unavailable: %v", err))
|
||
|
}
|
||
|
return id
|
||
|
}
|