diff --git a/x/model/name.go b/x/model/name.go index 84a99d09..7b646291 100644 --- a/x/model/name.go +++ b/x/model/name.go @@ -188,27 +188,30 @@ func (r Name) MapHash() uint64 { return h.Sum64() } +// DisplayModel returns the a display string of the model. func (r Name) DisplayModel() string { return r.model } -func (r Name) DisplayFull() string { +// DisplayComplete returns a complete display string of the Name. For any +// part that is missing, a ("?") is used. If a complete name is not required +// and only the longest possible name is needed, use [Name.String] or +// String or check if [Name.Complete] is true before calling. +// +// It does not include the build. +func (r Name) DisplayComplete() string { return (Name{ - host: cmp.Or(r.host, "!(MISSING DOMAIN)"), - namespace: cmp.Or(r.namespace, "!(MISSING NAMESPACE)"), - model: cmp.Or(r.model, "!(MISSING NAME)"), - tag: cmp.Or(r.tag, "!(MISSING TAG)"), - build: cmp.Or(r.build, "!(MISSING BUILD)"), + host: cmp.Or(r.host, "?"), + namespace: cmp.Or(r.namespace, "?"), + model: cmp.Or(r.model, "?"), + tag: cmp.Or(r.tag, "?"), }).String() } -// DisplayCompact returns a compact display string of the Name with only the -// model and tag parts. -func (r Name) DisplayCompact() string { - return (Name{ - model: r.model, - tag: r.tag, - }).String() +// GoString implements fmt.GoStringer. It is identical to +// [Name.DisplayComplete], but works with fmt.Printf("%#v", name). +func (r Name) GoString() string { + return r.DisplayComplete() } // DisplayShort returns a short display string of the Name with only the @@ -217,7 +220,6 @@ func (r Name) DisplayShort() string { return (Name{ model: r.model, tag: r.tag, - build: r.build, }).String() } @@ -228,7 +230,6 @@ func (r Name) DisplayLong() string { namespace: r.namespace, model: r.model, tag: r.tag, - build: r.build, }).String() } diff --git a/x/model/name_test.go b/x/model/name_test.go index cae0861f..8b295b2a 100644 --- a/x/model/name_test.go +++ b/x/model/name_test.go @@ -156,57 +156,78 @@ func TestComplete(t *testing.T) { } } -func TestNameStringVariants(t *testing.T) { +func TestNameDisplay(t *testing.T) { cases := []struct { - in string - nameAndTag string - nameTagAndBuild string + name string + in string + wantShort string + wantLong string + wantComplete string + wantString string + wantModel string }{ - {"x/y/z:8n+I", "z:8n", "z:8n+I"}, - {"x/y/z:8n", "z:8n", "z:8n"}, + { + name: "Full Name with Build", + in: "example.com/library/mistral:latest+Q4_0", + wantShort: "mistral:latest", + wantLong: "library/mistral:latest", + wantComplete: "example.com/library/mistral:latest", + wantModel: "mistral", + }, + { + name: "Complete Name", + in: "example.com/library/mistral:latest+Q4_0", + wantShort: "mistral:latest", + wantLong: "library/mistral:latest", + wantComplete: "example.com/library/mistral:latest", + wantModel: "mistral", + }, + { + name: "Short Name", + in: "mistral:latest", + wantShort: "mistral:latest", + wantLong: "mistral:latest", + wantComplete: "?/?/mistral:latest", + wantModel: "mistral", + }, + { + name: "Long Name", + in: "library/mistral:latest", + wantShort: "mistral:latest", + wantLong: "library/mistral:latest", + wantComplete: "?/library/mistral:latest", + wantModel: "mistral", + }, + { + name: "Case Preserved", + in: "Library/Mistral:Latest", + wantShort: "Mistral:Latest", + wantLong: "Library/Mistral:Latest", + wantComplete: "?/Library/Mistral:Latest", + wantModel: "Mistral", + }, } for _, tt := range cases { - t.Run(tt.in, func(t *testing.T) { + t.Run(tt.name, func(t *testing.T) { p := ParseName(tt.in) - t.Logf("ParseName(%q) = %#v", tt.in, p) - if g := p.DisplayCompact(); g != tt.nameAndTag { - t.Errorf("ModelAndTag(%q) = %q; want %q", tt.in, g, tt.nameAndTag) + if g := p.DisplayShort(); g != tt.wantShort { + t.Errorf("DisplayShort = %q; want %q", g, tt.wantShort) } - if g := p.DisplayShort(); g != tt.nameTagAndBuild { - t.Errorf("ModelTagAndBuild(%q) = %q; want %q", tt.in, g, tt.nameTagAndBuild) + if g := p.DisplayLong(); g != tt.wantLong { + t.Errorf("DisplayLong = %q; want %q", g, tt.wantLong) } - }) - } -} - -func TestNameFull(t *testing.T) { - const empty = "!(MISSING DOMAIN)/!(MISSING NAMESPACE)/!(MISSING NAME):!(MISSING TAG)+!(MISSING BUILD)" - - cases := []struct { - in string - wantFull string - }{ - {"", empty}, - {"ns/mistral:7b+x", "!(MISSING DOMAIN)/ns/mistral:7b+X"}, - {"ns/mistral:7b+Q4_0", "!(MISSING DOMAIN)/ns/mistral:7b+Q4_0"}, - {"example.com/x/mistral:latest", "example.com/x/mistral:latest+!(MISSING BUILD)"}, - {"example.com/x/mistral:latest+Q4_0", "example.com/x/mistral:latest+Q4_0"}, - - {"mistral:7b+x", "!(MISSING DOMAIN)/!(MISSING NAMESPACE)/mistral:7b+X"}, - {"mistral:7b+q4_0", "!(MISSING DOMAIN)/!(MISSING NAMESPACE)/mistral:7b+Q4_0"}, - {"mistral:7b+Q4_0", "!(MISSING DOMAIN)/!(MISSING NAMESPACE)/mistral:7b+Q4_0"}, - {"mistral:latest", "!(MISSING DOMAIN)/!(MISSING NAMESPACE)/mistral:latest+!(MISSING BUILD)"}, - {"mistral", "!(MISSING DOMAIN)/!(MISSING NAMESPACE)/mistral:!(MISSING TAG)+!(MISSING BUILD)"}, - {"mistral:30b", "!(MISSING DOMAIN)/!(MISSING NAMESPACE)/mistral:30b+!(MISSING BUILD)"}, - } - - for _, tt := range cases { - t.Run(tt.in, func(t *testing.T) { - p := ParseName(tt.in) - t.Logf("ParseName(%q) = %#v", tt.in, p) - if g := p.DisplayFull(); g != tt.wantFull { - t.Errorf("DisplayFull(%q) = %q; want %q", tt.in, g, tt.wantFull) + if g := p.DisplayComplete(); g != tt.wantComplete { + t.Errorf("DisplayComplete = %q; want %q", g, tt.wantComplete) + } + if g := p.String(); g != tt.in { + t.Errorf("String(%q) = %q; want %q", tt.in, g, tt.in) + } + if g := p.Model(); g != tt.wantModel { + t.Errorf("Model = %q; want %q", g, tt.wantModel) + } + if g, w := fmt.Sprintf("%#v", p), p.DisplayComplete(); g != w { + t.Errorf("GoString() = %q; want %q", g, w) } }) }