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 }