123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- package model
- import (
- "fmt"
- "log/slog"
- "strings"
- "unicode"
- )
- // Digest represents a digest of a model Manifest. It is a comparable value
- // type and is immutable.
- //
- // The zero Digest is not a valid digest.
- type Digest struct {
- s string
- }
- // Split returns the digest type and the digest value.
- func (d Digest) Split() (typ, digest string) {
- typ, digest, _ = strings.Cut(d.s, "-")
- return
- }
- // 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 }
- // 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 != "" }
- // LogValue implements slog.Value.
- func (d Digest) LogValue() slog.Value {
- return slog.StringValue(d.String())
- }
- var (
- _ slog.LogValuer = Digest{}
- )
- // ParseDigest parses a string in the form of "<digest-type>-<digest>" into a
- // Digest.
- func ParseDigest(s string) Digest {
- typ, digest, ok := strings.Cut(s, "-")
- if !ok {
- typ, digest, ok = strings.Cut(s, ":")
- }
- if ok && isValidDigestType(typ) && isValidHex(digest) && len(digest) >= 2 {
- return Digest{s: fmt.Sprintf("%s-%s", typ, digest)}
- }
- return Digest{}
- }
- func MustParseDigest(s string) Digest {
- d := ParseDigest(s)
- if !d.IsValid() {
- panic(fmt.Sprintf("invalid digest: %q", s))
- }
- return d
- }
- func isValidDigestType(s string) bool {
- if len(s) == 0 {
- return false
- }
- for _, r := range s {
- if !unicode.IsLower(r) && !unicode.IsDigit(r) {
- return false
- }
- }
- return true
- }
- func isValidHex(s string) bool {
- if len(s) == 0 {
- return false
- }
- for i := range s {
- c := s[i]
- if c < '0' || c > '9' && c < 'a' || c > 'f' {
- return false
- }
- }
- return true
- }
|