From 0cf76807c2f1ababf47fed47e8cf4791eabdd526 Mon Sep 17 00:00:00 2001 From: Virgil Date: Sat, 4 Apr 2026 06:45:34 +0000 Subject: [PATCH] Add lookup catalog boolean helpers --- lns.go | 46 +++++++++++++++++++++++++++++ lns_package_test.go | 72 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) diff --git a/lns.go b/lns.go index 0dfab31..4b692da 100644 --- a/lns.go +++ b/lns.go @@ -614,6 +614,29 @@ func GetLookupCatalogName[T any]( return LookupCatalogName(name, byLabel, byHash) } +// HasLookupCatalogName reports whether LookupCatalogName can resolve the input. +// +// ok := lns.HasLookupCatalogName(name, byLabel, byHash) +func HasLookupCatalogName[T any]( + name any, + byLabel func(string) (T, bool), + byHash func(primitives.Hash) (T, bool), +) bool { + _, ok := LookupCatalogName(name, byLabel, byHash) + return ok +} + +// GetHasLookupCatalogName is an alias for HasLookupCatalogName. +// +// ok := lns.GetHasLookupCatalogName(name, byLabel, byHash) +func GetHasLookupCatalogName[T any]( + name any, + byLabel func(string) (T, bool), + byHash func(primitives.Hash) (T, bool), +) bool { + return HasLookupCatalogName(name, byLabel, byHash) +} + func lookupCatalogName[T any]( name any, byLabel func(string) (T, bool), @@ -648,6 +671,29 @@ func (s *Service) GetLookupCatalogName( return s.LookupCatalogName(name, byLabel, byHash) } +// HasLookupCatalogName reports whether LookupCatalogName can resolve the input. +// +// ok := svc.HasLookupCatalogName(name, byLabel, byHash) +func (s *Service) HasLookupCatalogName( + name any, + byLabel func(string) (any, bool), + byHash func(primitives.Hash) (any, bool), +) bool { + _, ok := s.LookupCatalogName(name, byLabel, byHash) + return ok +} + +// GetHasLookupCatalogName is an alias for HasLookupCatalogName. +// +// ok := svc.GetHasLookupCatalogName(name, byLabel, byHash) +func (s *Service) GetHasLookupCatalogName( + name any, + byLabel func(string) (any, bool), + byHash func(primitives.Hash) (any, bool), +) bool { + return s.HasLookupCatalogName(name, byLabel, byHash) +} + // Resolve returns the canonical hash for a validated .lthn name. // // This is the package-level convenience wrapper around Service.Resolve. diff --git a/lns_package_test.go b/lns_package_test.go index 289b504..6b27a14 100644 --- a/lns_package_test.go +++ b/lns_package_test.go @@ -520,6 +520,34 @@ func TestLookupCatalogNamePreservesDottedLabels(t *testing.T) { t.Fatalf("GetLookupCatalogName should alias LookupCatalogName, got %q ok=%v", got, ok) } + if !HasLookupCatalogName( + "foo.bar", + func(name string) (string, bool) { + item, ok := byLabel[name] + return item, ok + }, + func(name primitives.Hash) (string, bool) { + item, ok := byHash[name] + return item, ok + }, + ) { + t.Fatal("HasLookupCatalogName should report a dotted raw label match") + } + + if !GetHasLookupCatalogName( + "FOO.BAR.LTHN", + func(name string) (string, bool) { + item, ok := byLabel[name] + return item, ok + }, + func(name primitives.Hash) (string, bool) { + item, ok := byHash[name] + return item, ok + }, + ) { + t.Fatal("GetHasLookupCatalogName should alias HasLookupCatalogName") + } + svc := NewService(nil) gotAny, ok := svc.LookupCatalogName( @@ -559,6 +587,34 @@ func TestLookupCatalogNamePreservesDottedLabels(t *testing.T) { if !ok || gotStr != "hash" { t.Fatalf("svc.GetLookupCatalogName should alias svc.LookupCatalogName, got %v ok=%v", gotAny, ok) } + + if !svc.HasLookupCatalogName( + "foo.bar", + func(name string) (any, bool) { + item, ok := byLabel[name] + return any(item), ok + }, + func(name primitives.Hash) (any, bool) { + item, ok := byHash[name] + return any(item), ok + }, + ) { + t.Fatal("svc.HasLookupCatalogName should report a dotted raw label match") + } + + if !svc.GetHasLookupCatalogName( + "FOO.BAR.LTHN", + func(name string) (any, bool) { + item, ok := byLabel[name] + return any(item), ok + }, + func(name primitives.Hash) (any, bool) { + item, ok := byHash[name] + return any(item), ok + }, + ) { + t.Fatal("svc.GetHasLookupCatalogName should alias svc.HasLookupCatalogName") + } } func TestLookupCatalogNameNilCallbacks(t *testing.T) { @@ -570,6 +626,14 @@ func TestLookupCatalogNameNilCallbacks(t *testing.T) { t.Fatalf("GetLookupCatalogName with nil callbacks = (%q, %v), want (\"\", false)", got, ok) } + if ok := HasLookupCatalogName[string]("foo", nil, nil); ok { + t.Fatal("HasLookupCatalogName with nil callbacks should return false") + } + + if ok := GetHasLookupCatalogName[string]("foo", nil, nil); ok { + t.Fatal("GetHasLookupCatalogName with nil callbacks should return false") + } + svc := NewService(nil) if got, ok := svc.LookupCatalogName("foo", nil, nil); ok || got != nil { @@ -579,6 +643,14 @@ func TestLookupCatalogNameNilCallbacks(t *testing.T) { if got, ok := svc.GetLookupCatalogName("foo", nil, nil); ok || got != nil { t.Fatalf("svc.GetLookupCatalogName with nil callbacks = (%v, %v), want (nil, false)", got, ok) } + + if ok := svc.HasLookupCatalogName("foo", nil, nil); ok { + t.Fatal("svc.HasLookupCatalogName with nil callbacks should return false") + } + + if ok := svc.GetHasLookupCatalogName("foo", nil, nil); ok { + t.Fatal("svc.GetHasLookupCatalogName with nil callbacks should return false") + } } func TestPackageTypeTables(t *testing.T) {