types/model: remove Digest (for now) (#3970)
The Digest type needs more thought and is not necessary at the moment.
This commit is contained in:
parent
aad8d128a0
commit
2bed62926e
2 changed files with 4 additions and 140 deletions
|
@ -4,7 +4,6 @@ package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"cmp"
|
"cmp"
|
||||||
"encoding/hex"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
@ -171,11 +170,6 @@ func Merge(a, b Name) Name {
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
// Digest returns the result of [ParseDigest] with the RawDigest field.
|
|
||||||
func (n Name) Digest() Digest {
|
|
||||||
return ParseDigest(n.RawDigest)
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the name string, in the format that [ParseNameNoDefaults]
|
// String returns the name string, in the format that [ParseNameNoDefaults]
|
||||||
// accepts as valid, if [Name.IsValid] reports true; otherwise the empty
|
// accepts as valid, if [Name.IsValid] reports true; otherwise the empty
|
||||||
// string is returned.
|
// string is returned.
|
||||||
|
@ -204,7 +198,7 @@ func (n Name) String() string {
|
||||||
// IsValid reports whether all parts of the name are present and valid. The
|
// IsValid reports whether all parts of the name are present and valid. The
|
||||||
// digest is a special case, and is checked for validity only if present.
|
// digest is a special case, and is checked for validity only if present.
|
||||||
func (n Name) IsValid() bool {
|
func (n Name) IsValid() bool {
|
||||||
if n.RawDigest != "" && !ParseDigest(n.RawDigest).IsValid() {
|
if n.RawDigest != "" && !isValidPart(kindDigest, n.RawDigest) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return n.IsFullyQualified()
|
return n.IsFullyQualified()
|
||||||
|
@ -282,7 +276,7 @@ func isValidPart(kind partKind, s string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
case ':':
|
case ':':
|
||||||
if kind != kindHost {
|
if kind != kindHost && kind != kindDigest {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -317,75 +311,3 @@ func cutPromised(s, sep string) (before, after string, ok bool) {
|
||||||
}
|
}
|
||||||
return cmp.Or(before, MissingPart), cmp.Or(after, MissingPart), true
|
return cmp.Or(before, MissingPart), cmp.Or(after, MissingPart), true
|
||||||
}
|
}
|
||||||
|
|
||||||
type DigestType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
DigestTypeInvalid DigestType = iota
|
|
||||||
DigestTypeSHA256
|
|
||||||
)
|
|
||||||
|
|
||||||
func (t DigestType) String() string {
|
|
||||||
if t == DigestTypeSHA256 {
|
|
||||||
return "sha256"
|
|
||||||
}
|
|
||||||
return "unknown"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Digest represents a type and hash of a digest. It is comparable and can
|
|
||||||
// be used as a map key.
|
|
||||||
type Digest struct {
|
|
||||||
Type DigestType
|
|
||||||
Hash [32]byte
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseDigest parses a digest string into a Digest struct. It accepts both
|
|
||||||
// the forms:
|
|
||||||
//
|
|
||||||
// sha256:deadbeef
|
|
||||||
// sha256-deadbeef
|
|
||||||
//
|
|
||||||
// The hash part must be exactly 64 characters long.
|
|
||||||
//
|
|
||||||
// The form "type:hash" does not round trip through [Digest.String].
|
|
||||||
func ParseDigest(s string) Digest {
|
|
||||||
typ, hash, ok := cutLast(s, ":")
|
|
||||||
if !ok {
|
|
||||||
typ, hash, ok = cutLast(s, "-")
|
|
||||||
if !ok {
|
|
||||||
return Digest{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if typ != "sha256" {
|
|
||||||
return Digest{}
|
|
||||||
}
|
|
||||||
var d Digest
|
|
||||||
n, err := hex.Decode(d.Hash[:], []byte(hash))
|
|
||||||
if err != nil || n != 32 {
|
|
||||||
return Digest{}
|
|
||||||
}
|
|
||||||
return Digest{Type: DigestTypeSHA256, Hash: d.Hash}
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsValid returns true if the digest has a valid Type and Hash.
|
|
||||||
func (d Digest) IsValid() bool {
|
|
||||||
if d.Type != DigestTypeSHA256 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return d.Hash != [32]byte{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the digest as a string in the form "type-hash". The hash
|
|
||||||
// is encoded as a hex string.
|
|
||||||
func (d Digest) String() string {
|
|
||||||
var b strings.Builder
|
|
||||||
b.WriteString(d.Type.String())
|
|
||||||
b.WriteByte('-')
|
|
||||||
b.WriteString(hex.EncodeToString(d.Hash[:]))
|
|
||||||
return b.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// LogValue returns a slog.Value that represents the digest as a string.
|
|
||||||
func (d Digest) LogValue() slog.Value {
|
|
||||||
return slog.StringValue(d.String())
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -82,10 +81,10 @@ func TestParseNameParts(t *testing.T) {
|
||||||
wantValidDigest: false,
|
wantValidDigest: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
in: "model@sha256:" + validSHA256Hex,
|
in: "model@sha256:123",
|
||||||
want: Name{
|
want: Name{
|
||||||
Model: "model",
|
Model: "model",
|
||||||
RawDigest: "sha256:" + validSHA256Hex,
|
RawDigest: "sha256:123",
|
||||||
},
|
},
|
||||||
wantValidDigest: true,
|
wantValidDigest: true,
|
||||||
},
|
},
|
||||||
|
@ -97,9 +96,6 @@ func TestParseNameParts(t *testing.T) {
|
||||||
if !reflect.DeepEqual(got, tt.want) {
|
if !reflect.DeepEqual(got, tt.want) {
|
||||||
t.Errorf("parseName(%q) = %v; want %v", tt.in, got, tt.want)
|
t.Errorf("parseName(%q) = %v; want %v", tt.in, got, tt.want)
|
||||||
}
|
}
|
||||||
if got.Digest().IsValid() != tt.wantValidDigest {
|
|
||||||
t.Errorf("parseName(%q).Digest().IsValid() = %v; want %v", tt.in, got.Digest().IsValid(), tt.wantValidDigest)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -239,57 +235,3 @@ func FuzzName(f *testing.F) {
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const validSHA256Hex = "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789"
|
|
||||||
|
|
||||||
func TestParseDigest(t *testing.T) {
|
|
||||||
cases := map[string]bool{
|
|
||||||
"sha256-1000000000000000000000000000000000000000000000000000000000000000": true,
|
|
||||||
"sha256:1000000000000000000000000000000000000000000000000000000000000000": true,
|
|
||||||
"sha256:0000000000000000000000000000000000000000000000000000000000000000": false,
|
|
||||||
|
|
||||||
"sha256:" + validSHA256Hex: true,
|
|
||||||
"sha256-" + validSHA256Hex: true,
|
|
||||||
|
|
||||||
"": false,
|
|
||||||
"sha134:" + validSHA256Hex: false,
|
|
||||||
"sha256:" + validSHA256Hex + "x": false,
|
|
||||||
"sha256:x" + validSHA256Hex: false,
|
|
||||||
"sha256-" + validSHA256Hex + "x": false,
|
|
||||||
"sha256-x": false,
|
|
||||||
}
|
|
||||||
|
|
||||||
for s, want := range cases {
|
|
||||||
t.Run(s, func(t *testing.T) {
|
|
||||||
d := ParseDigest(s)
|
|
||||||
if d.IsValid() != want {
|
|
||||||
t.Errorf("ParseDigest(%q).IsValid() = %v; want %v", s, d.IsValid(), want)
|
|
||||||
}
|
|
||||||
norm := strings.ReplaceAll(s, ":", "-")
|
|
||||||
if d.IsValid() && d.String() != norm {
|
|
||||||
t.Errorf("ParseDigest(%q).String() = %q; want %q", s, d.String(), norm)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDigestString(t *testing.T) {
|
|
||||||
cases := []struct {
|
|
||||||
in string
|
|
||||||
want string
|
|
||||||
}{
|
|
||||||
{in: "sha256:" + validSHA256Hex, want: "sha256-" + validSHA256Hex},
|
|
||||||
{in: "sha256-" + validSHA256Hex, want: "sha256-" + validSHA256Hex},
|
|
||||||
{in: "", want: "unknown-0000000000000000000000000000000000000000000000000000000000000000"},
|
|
||||||
{in: "blah-100000000000000000000000000000000000000000000000000000000000000", want: "unknown-0000000000000000000000000000000000000000000000000000000000000000"},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range cases {
|
|
||||||
t.Run(tt.in, func(t *testing.T) {
|
|
||||||
d := ParseDigest(tt.in)
|
|
||||||
if d.String() != tt.want {
|
|
||||||
t.Errorf("ParseDigest(%q).String() = %q; want %q", tt.in, d.String(), tt.want)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue