x/model: more Digest docs

This commit is contained in:
Blake Mizerany 2024-04-07 20:24:06 -07:00
parent 06c21f00eb
commit d3c6400487
2 changed files with 26 additions and 6 deletions

View File

@ -10,26 +10,40 @@ import (
"unicode" "unicode"
) )
// Digest is an opaque reference to a model digest. It holds the digest type // Digest represents a digest of a model Manifest. It is a comparable value
// and the digest itself. // type and is immutable.
// //
// It is comparable with other Digests and can be used as a map key. // The zero Digest is not a valid digest.
type Digest struct { type Digest struct {
s string s string
} }
// Type returns the digest type of the digest.
//
// Example:
//
// ParseDigest("sha256-1234").Type() // returns "sha256"
func (d Digest) Type() string { func (d Digest) Type() string {
typ, _, _ := strings.Cut(d.s, "-") typ, _, _ := strings.Cut(d.s, "-")
return typ return typ
} }
func (d Digest) IsValid() bool { return d.s != "" } // String returns the digest in the form of "<digest-type>-<digest>", or the
// empty string if the digest is invalid.
func (d Digest) String() string { return d.s } func (d Digest) String() string { return d.s }
// IsValid returns true if the digest is valid (not zero).
//
// A valid digest may be created only by ParseDigest, or
// ParseName(name).Digest().
func (d Digest) IsValid() bool { return d.s != "" }
// MarshalText implements encoding.TextMarshaler.
func (d Digest) MarshalText() ([]byte, error) { func (d Digest) MarshalText() ([]byte, error) {
return []byte(d.String()), nil return []byte(d.String()), nil
} }
// UnmarshalText implements encoding.TextUnmarshaler.
func (d *Digest) UnmarshalText(text []byte) error { func (d *Digest) UnmarshalText(text []byte) error {
if d.IsValid() { if d.IsValid() {
return errors.New("model.Digest: illegal UnmarshalText on valid Digest") return errors.New("model.Digest: illegal UnmarshalText on valid Digest")
@ -38,15 +52,18 @@ func (d *Digest) UnmarshalText(text []byte) error {
return nil return nil
} }
// LogValue implements slog.Value.
func (d Digest) LogValue() slog.Value { func (d Digest) LogValue() slog.Value {
return slog.StringValue(d.String()) return slog.StringValue(d.String())
} }
var ( var (
_ driver.Valuer = Digest{} _ driver.Valuer = Digest{}
_ sql.Scanner = (*Digest)(nil) _ sql.Scanner = (*Digest)(nil)
_ slog.LogValuer = Digest{}
) )
// Scan implements the sql.Scanner interface.
func (d *Digest) Scan(src any) error { func (d *Digest) Scan(src any) error {
if d.IsValid() { if d.IsValid() {
return errors.New("model.Digest: illegal Scan on valid Digest") return errors.New("model.Digest: illegal Scan on valid Digest")
@ -62,6 +79,7 @@ func (d *Digest) Scan(src any) error {
return fmt.Errorf("model.Digest: invalid Scan source %T", src) return fmt.Errorf("model.Digest: invalid Scan source %T", src)
} }
// Value implements the driver.Valuer interface.
func (d Digest) Value() (driver.Value, error) { func (d Digest) Value() (driver.Value, error) {
return d.String(), nil return d.String(), nil
} }

View File

@ -32,6 +32,8 @@ type PartKind int
// Levels of concreteness // Levels of concreteness
const ( const (
// Each value aligns with its index in the Name.parts array.
PartHost PartKind = iota PartHost PartKind = iota
PartNamespace PartNamespace
PartModel PartModel