package search
// Service holds the registered providers and routing defaults.
//
// It's stateless apart from configuration, so a single instance is shared
// across all HTTP handlers.
type Service struct {
providers map[string]Provider
defaultProvider string
publicURL string
}
// NewService constructs a search service with the built-in provider set.
//
// defaultProvider must be the ID of one of the built-in providers; the
// loader-time validator guarantees this, but we re-check at startup so a
// programmer mistake fails loudly rather than silently picking something.
func NewService(defaultProvider, publicURL string) (*Service, error) {
providers := providerByID()
if _, ok := providers[defaultProvider]; !ok {
return nil, ErrUnknownProvider{ID: defaultProvider}
}
return &Service{
providers: providers,
defaultProvider: defaultProvider,
publicURL: publicURL,
}, nil
}
// Providers returns all registered providers in the canonical order.
func (s *Service) Providers() []Provider {
return AllProviders()
}
// Lookup returns a provider by ID, or false if not registered.
func (s *Service) Lookup(id string) (Provider, bool) {
p, ok := s.providers[id]
return p, ok
}
// Route resolves a raw query into a (provider, cleaned-query) pair.
func (s *Service) Route(raw string) (Provider, string, error) {
return Route(raw, s.providers, s.defaultProvider)
}
// PublicURL returns the externally-visible URL of this service, used to
// build self-referential OpenSearch description documents.
func (s *Service) PublicURL() string {
return s.publicURL
}
// ErrUnknownProvider is returned when a provider ID is referenced but not
// registered. It's a typed error so callers can distinguish it from
// validation failures higher up the stack.
type ErrUnknownProvider struct{ ID string }
func (e ErrUnknownProvider) Error() string {
return "unknown provider: " + e.ID
}